Thursday, April 4, 2019

Revoke expired certificates from VMware vCSA with Embedded PSC

I was receiving errors indicating I had expired certificates in my vCenter, even though I had used the certificate manager to go through a complete refresh of the certificates. All the VMware KB articles that pointed me to the vecs-cli were fruitless. The certificate would say it successfully deleted, but it wouldn't actually delete. The following are steps I followed with support to get the certificates removed. (Note...this is not an officially supported method of removal by VMware...so continue at your own risk and create a snapshot of the vCSA before you proceed).

The process is to export the certs to crt files in the /tmp directory. Next run a script that scans all crt files for expired certificates, and then revokes all certificates that are expired.

  1. Create gencerts.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import re
import os
import subprocess

class SearchFunctions( object ):
    def __init__( self, rawdatas ):
        block_expr = re.findall(b"^-+BEGIN CERTIFICATE-+.*?-+END CERTIFICATE-+\s",rawdatas,re.DOTALL|re.MULTILINE)
        self.GetData = block_expr ###### get results
        print("-- Done with data parse.")
######  Main function
class dataParse( object ):
    def __init__( self, rawdatas ):
        count = 1

        print("\n-- Running data parse...")
        sa = SearchFunctions(rawdatas)

        print("-- Begin writing certs to files...")
        for i in sa.GetData:
            i = i.decode("utf-8")
            file_name = 'cert%s.crt' % count
            with open(file_name, 'w') as f:
                print("- Writing cert to %s" % file_name)
                f.write(i)
                count = count+1

def main():
    usage="use it right"
    print("-- Enumerating certs.  Counting...")
    p = subprocess.check_output(["/usr/lib/vmware-vmca/bin/certool","--enumcert","--filter=all"])
    dataParse(p)
if __name__ == "__main__":

    main()

  1. Run ./gencerts.py
  1. Create Find-expired.sh
#!/bin/bash
CERTFILE=$1

if openssl x509 -checkend 86400 -in $CERTFILE 2> /dev/null | grep -q "Certificate will not expire"
then
        echo "$CERTFILE is still valid.  Skipping..."
elif openssl x509 -checkend 86400 -in $CERTFILE 2> /dev/null | grep -q "Certificate will expire"
then
    echo -e "\nCertificate is expired!  Adding $CERTFILE to expiredcerts.txt...\n"
    echo "$CERTFILE" >> expiredcerts.txt
else
    echo -e "\nthere was a problem checking the cert.  ignoring $CERTFILE.\n"
fi

  1. Run "for i in $(ls cert*.crt); do ./find-expired.sh $i ; done"
  1. Run "for i in $(cat expiredcerts.txt); do /usr/lib/vmware-vmca/bin/certool --revokecert --cert /tmp/$i ;done"
  2. Validate the certificates are all revoked, then delete the snapshot you created.