Revoking TAK Client Certificates Easy
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.
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