def _closeup(self): x509cert = pki_utils.x509_load_cert( oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT, ) self.dialog.note( text=_('Internal CA fingerprint: SHA256: {fingerprint}').format( fingerprint=re.sub( r'(..)', r':\1', binascii.b2a_hex( x509cert.fingerprint( algorithm=hashes.SHA256() ) ).decode().upper() )[1:], ) ) for ca_file in self._renewed_ca_files: self.logger.warning( _( 'CA %s was renewed, please refresh manually ' 'distributed copies' ), ca_file )
def _customization_upgrade(self): if True in [ pki_utils.cert_expires(pki_utils.x509_load_cert(cert)) for cert in self._CA_FILES if os.path.exists(cert) ] + [ self._ok_to_renew_cert( os.path.join( oenginecons.FileLocations.OVIRT_ENGINE_PKIKEYSDIR, '%s.p12' % entry['name']), entry['name'], entry['extract']) for entry in self.environment[oenginecons.PKIEnv.ENTITIES] ]: if self.environment[oenginecons.PKIEnv.RENEW] is None: self.environment[oenginecons.PKIEnv.RENEW] = dialog.queryBoolean( dialog=self.dialog, name='OVESETUP_RENEW_PKI', note=_( 'One or more of the certificates should be renewed, ' 'because they expire soon, or include an invalid ' 'expiry date, or they were created with validity ' 'period longer than 398 days, or do not include the ' 'subjectAltName extension, which can cause them to be ' 'rejected by recent browsers and up to date hosts.\n' 'See {url} for more details.\n' 'Renew certificates? ' '(@VALUES@) [@DEFAULT@]: ').format( url=self.environment[ oenginecons.ConfigEnv.PKI_RENEWAL_DOC_URL], ), prompt=True, default=None, ) if not self.environment[oenginecons.PKIEnv.RENEW]: skip_renewal = dialog.queryBoolean( dialog=self.dialog, name='OVESETUP_SKIP_RENEW_PKI_CONFIRM', note=_( 'Are you really sure that you want to skip the ' 'PKI renewal process?\n' 'Please notice that recent openssl and gnutls ' 'upgrades can lead hosts refusing this CA cert ' 'making them unusable.\n' 'If you choose "Yes", setup will continue and you ' 'will be asked again the next ' 'time you run this Setup. Otherwise, this process ' 'will abort and you will be expected to plan a ' 'proper upgrade according to {url}.\n' 'Skip PKI renewal process? ' '(@VALUES@) [@DEFAULT@]: ').format( url=self.environment[oenginecons.ConfigEnv. PKI_RENEWAL_DOC_URL], ), prompt=True, default=False, ) if not skip_renewal: raise RuntimeError('Aborted by user')
def _ok_to_renew_cert(self, pkcs12, name, extract): # input: # - pkcs12: A PKCS#12 file name # - name: A base name (--name param of pki-* scripts) # - extract: bool. If True, we need to check the extracted cert # return: bool self.logger.debug("processing: '%s'", name) return os.path.exists(pkcs12) and pki_utils.ok_to_renew_cert( self.logger, self._extractPKCS12Certificate(pkcs12), pki_utils.x509_load_cert( oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT), name, extract, )
def _miscUpgrade(self): # # In <3.6 setup did not store the organization and # country in post install file. Load it from CA certificate. # if self.environment[oenginecons.PKIEnv.ORG] is None: ca = pki_utils.x509_load_cert( oenginecons.FileLocations. OVIRT_ENGINE_PKI_ENGINE_CA_CERT ) self.environment[ oenginecons.PKIEnv.ORG ] = ca.subject.get_attributes_for_oid( x509.oid.NameOID.ORGANIZATION_NAME )[0].value self.environment[ oenginecons.PKIEnv.COUNTRY ] = ca.subject.get_attributes_for_oid( x509.oid.NameOID.COUNTRY_NAME )[0].value self.logger.info(_('Upgrading CA')) # # LEGACY NOTE # Since 3.0 and maybe before the method of # allowing user to override AIA was to explict # edit files. Until we rewrite the entire PKI # we must preserve this approach. # The template may change over time, so regenerate. # def _template_aia(template): aia = None if os.path.exists(template): with open(template) as f: PREFIX = 'caIssuers;URI:' for line in f.read().splitlines(): if line.startswith('authorityInfoAccess'): aia = line[line.find(PREFIX)+len(PREFIX):] break return aia engine_aia = _template_aia(_CERT_TEMPLATE) qemu_aia = _template_aia(_QEMU_CERT_TEMPLATE) if qemu_aia is None: qemu_aia = self._calculated_aia( oenginecons.Const.ENGINE_PKI_QEMU_CA_URI ) if engine_aia and 'resource=qemu-ca-certificate' in engine_aia: # In the past, we had a single template for both engine and qemu # CAs, and it pointed at qemu cert. uninstall_info = self.environment[ osetupcons.CoreEnv.UNINSTALL_FILES_INFO ].get(_CERT_TEMPLATE) if uninstall_info and not uninstall_info.get("changed"): # It was written by engine-setup and not changed since. # It should be safe to replace it. engine_aia = self._calculated_aia( oenginecons.Const.ENGINE_PKI_CA_URI ) self.logger.info(_('Fixing {}'.format(_CERT_TEMPLATE))) self.dialog.note(_( 'This does not fix existing certificates.' )) else: self.logger.warn( _( '{template} has wrong data, but was manually changed ' 'after previous engine-setup' ).format( template=_CERT_TEMPLATE, ) ) self.dialog.note(_('Not fixing it.')) self.dialog.note(_( 'Please see also: https://bugzilla.redhat.com/1875386' )) uninstall_files = [] self._setupUninstall(uninstall_files) self._update_templates( engine_aia, _ENGINE_TEMPLATES_MAP, uninstall_files, ) self._update_templates( qemu_aia, _QEMU_TEMPLATES_MAP, uninstall_files, ) if self.environment[oenginecons.PKIEnv.RENEW]: for ca_file in self._CA_FILES: if ( os.path.exists(ca_file) and pki_utils.cert_expires(pki_utils.x509_load_cert(ca_file)) ): self._renewed_ca_files.add(ca_file) self.logger.info(_('Renewing CA: %s'), ca_file) args = ( oenginecons.FileLocations.OVIRT_ENGINE_PKI_CA_CREATE, '--renew', '--keystore-password=%s' % ( self.environment[oenginecons.PKIEnv.STORE_PASS], ), '--ca-file=%s' % (self._ca_file_name(ca_file),), ) self.execute( args=args, envAppend={ 'JAVA_HOME': self.environment[ oengcommcons.ConfigEnv.JAVA_HOME ], }, ) self._enrollCertificates(True, uninstall_files) # Also enroll missing parts on upgrade # We check just Engine CA, QEMU certificates are only on hosts if os.path.exists( oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT ): self._enrollCertificates(False, uninstall_files)
def enroll_cert(self): self.logger.debug('enroll_cert') cert = None self._need_cert = True if os.path.exists(self._cert_file): self._need_cert = False cert = pki_utils.x509_load_cert(self._cert_file) if pki_utils.ok_to_renew_cert( self.logger, cert, None, self._base_name, True, ): self._need_cert = True private_key = None self._need_key = True if os.path.exists(self._key_file): with open(self._key_file, 'rb') as f: private_key = serialization.load_pem_private_key( f.read(), password=None, backend=default_backend(), ) self._need_key = False else: self._need_cert = True self._key, self._csr, self._pubkey = self._genCsr(private_key) if self._need_cert: self._remote_name = '{name}-{fqdn}'.format( name=self._base_name, fqdn=self.environment[osetupcons.ConfigEnv.FQDN], ) self._enroll_command = ( " /usr/share/ovirt-engine/bin/pki-enroll-request.sh \\\n" " --name={remote_name} \\\n" " --subject=\"" "$(openssl x509 -in {engine_ca_cert_file} -text " "| sed -n 's; *DirName:\\(.*\\)/CN=.*;\\1;p')" "/CN={fqdn}\" \\\n" " --san=DNS:{fqdn}").format( remote_name=self._remote_name, engine_ca_cert_file=self._engine_ca_cert_file, fqdn=self.environment[osetupcons.ConfigEnv.FQDN], ) self._remote_engine.configure(fqdn=self._engine_fqdn) # TODO # This is ugly - we rely on having these two plugins # and do not support others. A good fix will: # 1. Be completely pluggable # 2. Will not duplicate the code in this function # 3. Will be nice to the user in every style # 4. Have a clearly-defined interface where relevant # Perhaps we'll have to give up on some of these, not sure # Also, for the meantime, we might/should implement # manual_inline and have another function for that, # or perhaps make _enroll_cert_manual_files work with both. cert = { osetupcons.Const.REMOTE_ENGINE_SETUP_STYLE_AUTO_SSH: (self._enroll_cert_auto_ssh), osetupcons.Const.REMOTE_ENGINE_SETUP_STYLE_MANUAL_FILES: (self._enroll_cert_manual_files), }[self._remote_engine.style().name]() self._cert = cert
def _refresh_needed(cert_path, check_cert=True): ca_cert_path = oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT return (not os.path.exists(cert_path) or os.stat(ca_cert_path).st_mtime > os.stat(cert_path).st_mtime or (check_cert and pki_utils.cert_expires(pki_utils.x509_load_cert(cert_path))))