Files
vmware-tools/vCert-6.1.1-20260401/operation/view_certificate.py
T
2026-06-23 11:27:54 +08:00

332 lines
14 KiB
Python

# Copyright (c) 2024 Broadcom. All Rights Reserved.
# The term "Broadcom" refers to Broadcom Inc.
# and/or its subsidiaries.
import logging
import OpenSSL
from datetime import datetime
from lib import vcdb
from lib import vecs
from lib import vmdir
from lib.environment import Environment
from lib.certificate_utils import (
get_certificate_info, get_certificate_fetcher_from_list, get_certificate_extensions,
build_certification_path, get_x509_certificate, get_subject_and_issuer_dn, get_subject_keyid,
is_ca_certificate, split_certificates_from_pem
)
from lib.console import print_header, print_text, print_text_warning, print_text_error, ColorKey
from lib.input import MenuInput
from lib.host_utils import get_file_contents
from lib.constants import VMCA_CERT_FILE_PATH
from lib.menu import Menu, MenuInput
from lib.vmdir import get_smart_card_issuing_ca_certs
from operation.check_certificate import get_ids_domain_and_certificates, get_ids_domain_and_certificates_by_domain
from operation.common import get_vcenter_extensions, get_vcenter_extension_expected_thumbprints
logger = logging.getLogger(__name__)
def view_certificate_dummy(**kwargs):
print_text("{}=== Unsupported view certificate operation! ==={}".format(ColorKey.YELLOW,
ColorKey.NORMAL))
def view_certificate(pem_cert):
print_header('Certificate Information')
print(get_certificate_info(pem_cert))
ca_certs, _ = vecs.get_all_certificates('TRUSTED_ROOTS')
subject_keyids, fetcher = get_certificate_fetcher_from_list(ca_certs)
cert_path = build_certification_path(pem_cert, subject_keyids, fetcher)
print_header('Certification Path')
print_certification_path(cert_path)
def print_certification_path(cert_path, status_text=False):
for idx, cert_info in enumerate(cert_path):
plus_green = "{}+{}".format(ColorKey.GREEN, ColorKey.NORMAL)
if idx == 0:
untrusted = '[UNTRUSTED]' if cert_info['is_trusted'] is not True else ''
incomplete = '[INCOMPLETE]' if cert_info['is_selfsigned'] is not True else ''
if untrusted or incomplete:
mark = "{}!{}".format(ColorKey.RED, ColorKey.NORMAL)
else:
mark = plus_green
if status_text:
print_text("[ {} ] {} {}{}".format(mark, cert_info['cert_name'], incomplete, untrusted))
else:
print_text("[ {} ] {}".format(mark, cert_info['cert_name']))
else:
print_text("{}|_[ {} ] {}".format(' ' * (4 * idx - 2), plus_green,
cert_info['cert_name']))
def view_machine_ssl_certificate():
cert = vecs.get_certificate('MACHINE_SSL_CERT', '__MACHINE_CERT')
view_certificate(cert)
def view_solution_user_certificate():
env = Environment.get_environment()
for soluser in env.get_value('SOLUTION_USERS'):
print(f"\nSolution User: {soluser}")
cert = vecs.get_certificate(soluser, soluser)
view_certificate(cert)
def view_data_encipherment_certificate():
cert = vecs.get_certificate('data-encipherment', 'data-encipherment')
view_certificate(cert)
def view_ca_certificates_in_vmdir(show_list_only=False):
print_header('CA Certificates in VMware Directory')
skids = vmdir.get_all_ca_subject_keyids(use_cache=False)
for index, subject_key_id in enumerate(skids):
cert_pem = vmdir.get_ca_certificate(subject_key_id)
brief = get_certificate_info_brief(cert_pem)
if index != 0:
print()
print("{:>2}. {}".format(index + 1, brief))
if show_list_only:
return
keys = [str(i) for i in range(1, len(skids) + 1)]
keys.append('R')
print()
menu_input = MenuInput('Select certificate [Return to menu]: ', acceptable_inputs=keys,
default_input='R')
key = menu_input.get_input()
print()
if key != 'R':
cert = vmdir.get_ca_certificate(skids[int(key)-1])
view_certificate(cert)
def view_certificates_in_vecs(store, show_list_only=False):
certs, aliases = vecs.get_all_certificates(store)
for idx, cert in enumerate(certs):
brief = get_certificate_info_brief(cert, aliases[idx])
print("{:>2}. {}\n".format(idx + 1, brief))
if show_list_only:
return
keys = [str(i) for i in range(1, len(aliases) + 1)]
keys.append('R')
menu_input = MenuInput('Select certificate [Return to menu]: ', acceptable_inputs=keys,
default_input='R')
key = menu_input.get_input()
print()
if key != 'R':
cert = certs[int(key) - 1]
view_certificate(cert)
def view_ca_certificates_in_vecs(show_list_only=False):
view_certificates_in_vecs('TRUSTED_ROOTS', show_list_only)
def view_sms_certificates_in_vecs(show_list_only=False):
view_certificates_in_vecs('SMS', show_list_only)
def view_sts_signing_certificates():
"""
Entry point for STS Tenant certificates view
"""
certs_map = vmdir.get_sts_tenant_certificates(include_tenant_credential=True,
include_certificate_chain=False)
for tenant_idx, tenant in enumerate(certs_map.keys()):
if tenant_idx != 0:
print()
print("{}".format(tenant))
for cert_idx, pem_cert in enumerate(certs_map[tenant]):
if cert_idx != 0:
print()
basic_constraints = get_certificate_extensions(
get_x509_certificate(pem_cert)).get('basicConstraints')
is_ca = basic_constraints is not None and 'CA:TRUE' in basic_constraints
print(" Certificate Type: {} Certificate".format('CA' if is_ca else 'Signing'))
brief = get_certificate_info_brief(pem_cert, indent_first_line=True)
print(brief)
def get_certificate_info_brief(pem_cert, alias=None, computed_skid=None, indent_first_line=False,
domain_name=None, identity_source_type=None):
"""
indent_first_line is used for 4 space indentation for first line of certificate info,
in this case, it is alias or subject.
"""
cert_info = []
try:
x509_cert = get_x509_certificate(pem_cert)
skid = get_subject_keyid(x509_cert)
subject_dn, issuer_dn = get_subject_and_issuer_dn(x509_cert)
# '20240708142450Z' -> 'Jul 8 14:24:50 2024 GMT'
input_format = '%Y%m%d%H%M%SZ'
output_format = '%b %e %H:%M:%S %Y GMT'
end_date = datetime.strptime(x509_cert.get_notAfter().decode('utf-8'), input_format).strftime(output_format)
if skid is None and computed_skid is not None:
skid = "{} (computed)".format(computed_skid)
is_ca = is_ca_certificate(x509_cert)
indentation = ' ' if indent_first_line else ''
if alias:
cert_info.append("{}Alias: {}".format(indentation, alias))
cert_info.append(" Subject: {}".format(subject_dn))
else:
cert_info.append("{}Subject: {}".format(indentation, subject_dn))
cert_info.append(" Issuer: {}".format(issuer_dn))
cert_info.append(" End Date: {}".format(end_date))
cert_info.append(" Subject Key ID: {}".format(skid))
cert_info.append(" Is CA Cert: {}".format('Yes' if is_ca else 'No'))
if domain_name is not None:
cert_info.append(' Domain: {}'.format(domain_name))
if identity_source_type is not None:
cert_info.append(' Identity Source Type: {}'.format(identity_source_type))
except OpenSSL.crypto.Error:
cert_info.append(print_text_error('Invalid format, certificate cannot be parsed', end=''))
cert_info.append(" Subject Key ID: {}".format(computed_skid))
return '\n'.join(cert_info)
def view_ldaps_identity_source_certificates(show_domain='All', identity_source_type=None, show_list_only=False):
header = 'LDAP Certificates' if show_domain == 'All' else 'LDAP Certificates ({})'.format(show_domain)
print_header(header)
identity_sources = vmdir.get_identity_sources()
index_start = 0
identity_source_certs = ['-']
if show_domain == 'All':
# OpenLDAP
index_start, identity_source_certs = ldaps_identity_source_certificate_items(identity_sources, index_start,
identity_source_certs, identity_source_type='OpenLDAP')
# AD over LDAP
index_start, identity_source_certs = ldaps_identity_source_certificate_items(identity_sources, index_start,
identity_source_certs, identity_source_type='AD over LDAP')
# ADFS
index_start, identity_source_certs = ldaps_identity_source_certificate_items(identity_sources, index_start,
identity_source_certs, identity_source_type='ADFS')
else:
index_start, identity_source_certs = ldaps_identity_source_certificate_items(identity_sources, index_start,
identity_source_certs, domain_name=show_domain,
identity_source_type=identity_source_type)
if show_list_only:
return identity_source_certs
print()
keys = [str(i) for i in range(1, len(identity_source_certs) + 1)]
keys.append('R')
menu_input = MenuInput('Select certificate [Return to menu]: ', acceptable_inputs=keys,
default_input='R')
key = menu_input.get_input()
print()
if key != 'R':
cert = identity_source_certs[int(key)]
view_certificate(cert)
return identity_source_certs
def ldaps_identity_source_certificate_items(identity_sources, index_start, identity_source_certs,
domain_name=None, identity_source_type=None):
if domain_name is None:
domain_and_certs = get_ids_domain_and_certificates(identity_sources, identity_source_type)
else:
domain_and_certs = get_ids_domain_and_certificates_by_domain(identity_sources, identity_source_type, domain_name)
if domain_and_certs:
for domain_name, certificates in domain_and_certs:
for index, cert in enumerate(certificates, index_start):
identity_source_certs.append(cert)
cert_info = get_certificate_info_brief(cert, domain_name=domain_name, identity_source_type=identity_source_type)
if index != 0:
print()
print("{:>2}. {}".format(index + 1, cert_info))
index_start += 1
return index_start, identity_source_certs
def view_VMCA_Certificate():
"""
Entry point to view VMCA Certificate
"""
view_certificate(get_file_contents(VMCA_CERT_FILE_PATH))
def view_vcenter_extension_thumbprints():
vcenter_extensions = get_vcenter_extensions()
extension_thumbprints = vcdb.get_extension_thumbprints(vcenter_extensions)
expected_thumbprints = get_vcenter_extension_expected_thumbprints(vcenter_extensions)
for extension, (thumbprint, db_cert_pem) in extension_thumbprints.items():
_, expected_cert_type, _ = expected_thumbprints[extension]
print("{} ({})".format(extension, expected_cert_type))
print(" ", thumbprint)
def view_smart_card_certificates(show_list_only=False):
smart_card_filter_file_certificates = view_smart_card_filter_file_certificates()
smart_card_vmdir_certificates = view_smart_card_vmdir_certificates()
if show_list_only:
return smart_card_filter_file_certificates, smart_card_vmdir_certificates
menu = Menu()
menu.set_menu_options('View Smart Card Certificate Options')
menu.add_menu_item('View Smart Card filter file certificate')
menu.add_menu_item('View Smart Card CA certificate')
menu.add_menu_item('Return to the previous menu', Menu.run_navigation_return, key='R', is_default=True, is_hidden=True,
use_label_as_key=True)
menu.show_menu()
print()
view_certificate_type = menu.get_input().strip()
if view_certificate_type != 'R':
if view_certificate_type == '1':
keys = [str(i) for i in range(1, len(smart_card_filter_file_certificates) + 1)]
keys.append('R')
print()
view_certificate_selection = MenuInput('Select Smart Card filter file certificate [Return to menu]: ', acceptable_inputs=keys, default_input='R').get_input()
if view_certificate_selection != 'R':
view_certificate(smart_card_filter_file_certificates[int(view_certificate_selection) - 1])
else:
keys = [str(i) for i in range(1, len(smart_card_vmdir_certificates) + 1)]
keys.append('R')
print()
view_certificate_selection = MenuInput('Select Smart Card CA certificate [Return to menu]: ', acceptable_inputs=keys, default_input='R').get_input()
if view_certificate_selection != 'R':
view_certificate(smart_card_vmdir_certificates[int(view_certificate_selection) - 1])
def view_smart_card_filter_file_certificates():
env = Environment.get_environment()
smart_card_filter_file = env.get_value('SMART_CARD_FILTER_FILE')
print_header('Smart Card Filter File Certificates')
smart_card_ca_certificates = split_certificates_from_pem(get_file_contents(smart_card_filter_file))
if smart_card_ca_certificates:
for index, cert in enumerate(smart_card_ca_certificates):
cert_info = get_certificate_info_brief(cert)
if index != 0:
print()
print("{:>2}. {}".format(index + 1, cert_info))
return smart_card_ca_certificates
else:
print_text_warning('No certificates found in {}'.format(smart_card_filter_file))
return []
def view_smart_card_vmdir_certificates():
smart_card_ca_certificates = get_smart_card_issuing_ca_certs()
logger.info('Smart Card CA Certifiates from VMware Directory: {}'.format(smart_card_ca_certificates))
print_header('Smart Card Issuing CA Certificates')
if smart_card_ca_certificates:
for index, cert in enumerate(smart_card_ca_certificates):
cert_info = get_certificate_info_brief(cert)
if index != 0:
print()
print("{:>2}. {}".format(index + 1, cert_info))
return smart_card_ca_certificates
else:
print_text_warning('No certificates found in VMware Directory')
return []