Revoking TAK Client Certificates Easy

👀
Attention: This method and script will only apply if your TAK Server is acting as the certificate authority for your clients.

In an older post on Creating TAK User Accounts easier we discussed how the account process is a multi-step task and how we can simplify this into one single command. The certificate revocation process is similar to this process and as such we need a simpler way to execute this task. Part of the revocation process requires (1) the certificate to be revoked, (2) the certificate authority, and (3) the certificate authority's private key. Additionally, it updates the certificate revocation list (crl) - a digital list of certificates that are revoked by the CA, an important part of the public key infrastructure environment (PKI/E).

The Basics

Before any shell script, we include the interpreter's language location #!/bin/bash, followed by some global variables. Aside from our global variables I've included some console color information to display errors and warnings. Here I've used the default red and yellow color identifiers; however, you can change them to your preference. More information on the console color codes can be found here. To remove our console colors we need to remove them after we are done so we assign the variable NC for this.

#!/bin/bash

dir=/opt/tak
certs=$dir/certs/files
revokeCert=$dir/certs/revokeCert.sh
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m'

After completing the header we need to verify that the current user is elevated. This is because the file we need to read cert-metadata.sh contains some key values used in our script later on.

# Determine if the user is root; else, use sudo
[ "$UID" -eq 0 ] || exec sudo "$0" "$@"

# Read the cert-metadata.sh file
. $dir/certs/cert-metadata.sh

After this, we do some input validation checks to see if a variable is provided on execution, if not we prompt for one. This is where we will assign the client variable which is the certificate to be revoked. We also want to create a basic function to call one of the basic errors we will get along the way. This is our display_err function that is returned if the client variable cannot be found.

# Determine if the first variable is declared
if [[ -n $1 ]]; then
    client=$1
else
    read -p 'Specify the client certificate to revoke: ' client
fi

display_err() {
    echo -e "${RED}Client Certificate: $client not found.${NC}"   
}

The Certificate Authority

To revoke the certificate we actually need to know a few things such as the certificate to be revoked, the private key associated with the CA, and the CA who issued the certificate. Many of these are done under the hood in the master revokeCert.sh command that comes with the TAK Server. Our script will do this for us so we just need to supply the certificate to be revoked. Additionally, we won't need to move between users or change ownership or permissions.

Finding the Issuing CA

Before we find out who our issuing CA is we need to find our certificate to be revoked - this is our client variable. If true, we want to use the openssl x509 command to view this certificate to find the issuing CA.

Example Openssl command

To only grab the information we need we use the grep command with REGEX. Additionally, we will strip the CN= from this output to only grab the issuing CA common name or subject name. Subsequently to fully apply the revoked certificate we conduct a check on our CoreConfig to ensure that we have the CRL element applied. If this element is not found we prompt a warning that the CRL element is not found and provide the string required in the CoreConfig. This CRL element can be found in the CoreConfig.example.xml for reference. If the Issuing CA is not found we default to the Root CA. This is because the makeCert.sh ca command was not executed as part of the initial CA setup process. Finally, in our first step if the client is not found we display the display_err function to identify that the certificate cannot be found.

# Determine the Issuing CA (.pem)
if [[ -f $certs/$client.pem ]]; then
    issuer=(`openssl x509 -text -in /opt/tak/certs/files/$client.pem | grep -Eo "CN=.+"`)
    issuer="${issuer[0]:3}"
    # Check CoreConfig for CA Element
    crl=(`cat /opt/tak/CoreConfig.xml | grep -Eo "<crl.+/>"`)
    if [[ -z "${crl[0]}" ]]; then
        echo -e "${YELLOW}CRL Element not found in Configuration.${NC}"
        echo -e "${YELLOW}Add the following line within the tls element within the CoreConfig to apply the revokation.${NC}"
        echo -e "${YELLOW}<crl _name="TAKServer CA" crlFile="certs/files/ca.crl"/>${NC}"
        echo -e "${YELLOW}Replace ca.crl with the appropriate crl file.${NC}"
        echo ""
    fi
# Find Issuing CA (.pem)
    if [[ -f $certs/${issuer[0]}.pem ]]; then
        ca="${issuer[0]}"
        key="${issuer[0]}"
    else
# Default Issuing CA
        echo "Issuing CA not found, reverting to default."
        ca="ca"
        key="ca-do-not-share"
    fi
else
    display_err
    exit 0
fi

Revoking the Certificate

Now that we conducted our logic checks for the certificate to be revoked and the issuing CA we can now revoke our certificate. Again, we will use the provided revokeCert.sh provided to complete this step using our captured values in our script. Once our certificate has been revoked, we will prompt to both ask to delete the revoked certificate and restart the TAK Server service to apply the revocation to take effect.

# Revoke the client certificate
if [[ -f $certs/$client.pem ]]; then
    cd $dir/certs || exit
    $revokeCert $certs/$client $certs/$key $certs/$ca
    read -p "Do you wish to delete the revoked certificate files? [y/n]:" DELETE
    if [[ $DELETE =~ ^[Yy] ]]; then
        rm -v $certs/$client.{pem,key,csr,jks}
    fi
    echo -e "${YELLOW}The TAK Server service must be restarted to apply the revocation.${NC}"
    read -p "Restart the TAK Server service? [y/n]:" RESTART
    if [[ $RESTART =~ ^[Yy] ]]; then
        systemctl restart takserver
    fi
else
# Client Certificate not found
    display_err
    exit 0
fi

Putting it all together

After we have compiled the various sections of our script we need to make our script executable. To do this we will use the chmod with the +x option to add the execute attribute to our file.

chmod +x revokeCert.sh

The Code

#!/bin/bash
#Version 1.0
#JR @myTeckNet.com
#Global Variables
dir=/opt/tak
certs=$dir/certs/files
revokeCert=$dir/certs/revokeCert.sh
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m'

# Determine if the user is root; else, use sudo
[ "$UID" -eq 0 ] || exec sudo "$0" "$@"

# Read the cert-metadata.sh file
. $dir/certs/cert-metadata.sh

# Determine if the first variable is declared
if [[ -n $1 ]]; then
    client=$1
else
    read -p 'Specify the client certificate to revoke: ' client
fi

display_err() {
    echo -e "${RED}Client Certificate: $client not found.${NC}"   
}

# Determine the Issuing CA (.pem)
if [[ -f $certs/$client.pem ]]; then
    issuer=(`openssl x509 -text -in /opt/tak/certs/files/$client.pem | grep -Eo "CN=.+"`)
    issuer="${issuer[0]:3}"
    # Check CoreConfig for CA Element
    crl=(`cat /opt/tak/CoreConfig.xml | grep -Eo "<crl.+/>"`)
    if [[ -z "${crl[0]}" ]]; then
        echo -e "${YELLOW}CRL Element not found in Configuration.${NC}"
        echo -e "${YELLOW}Add the following line within the tls element within the CoreConfig to apply the revokation.${NC}"
        echo -e "${YELLOW}<crl _name="TAKServer CA" crlFile="certs/files/ca.crl"/>${NC}"
        echo -e "${YELLOW}Replace ca.crl with the appropriate crl file.${NC}"
        echo ""
    fi
# Find Issuing CA (.pem)
    if [[ -f $certs/${issuer[0]}.pem ]]; then
        ca="${issuer[0]}"
        key="${issuer[0]}"
    else
# Default Issuing CA
        echo "Issuing CA not found, reverting to default."
        ca="ca"
        key="ca-do-not-share"
    fi
else
    display_err
    exit 0
fi

# Revoke the client certificate
if [[ -f $certs/$client.pem ]]; then
    cd $dir/certs || exit
    $revokeCert $certs/$client $certs/$key $certs/$ca
    read -p "Do you wish to delete the revoked certificate files? [y/n]:" DELETE
    if [[ $DELETE =~ ^[Yy] ]]; then
        rm -v $certs/$client.{pem,key,csr,jks}
    fi
    echo -e "${YELLOW}The TAK Server service must be restarted to apply the revocation.${NC}"
    read -p "Restart the TAK Server service? [y/n]:" RESTART
    if [[ $RESTART =~ ^[Yy] ]]; then
        systemctl restart takserver
    fi
else
# Client Certificate not found
    display_err
    exit 0
fi

Example Outputs

Example Output