Skip to content

Instantly share code, notes, and snippets.

@stevecheckoway
Created May 3, 2022 19:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevecheckoway/6bc602a66b7adad2df7e1a2b139ae902 to your computer and use it in GitHub Desktop.
Save stevecheckoway/6bc602a66b7adad2df7e1a2b139ae902 to your computer and use it in GitHub Desktop.
Script to create client certificates for Ghidra Server
#!/bin/bash
set -e
if [[ $# -ne 1 ]]; then
echo "Usage: $0 SID" >&2
exit 1
fi
### CONFIGURATION ###
# This is the same as Ghidra's sid
user_alias="$1"
# User certificate's distinguished name.
user_dn="CN=${user_alias}, O=YourOrg, C=US"
# Output file to give to user.
user_keystore="${user_alias}.p12"
# Password for the user's keystore.
user_password='ghidra'
# Keystore alias for the CA cert.
root_alias='root'
# CA's distinguished name.
root_dn='CN=GhidraRootCA, O=YourOrg, C=US'
# Path to CA's keystore.
root_keystore="${HOME}/ghidra-certs/keystore"
# Password for CA's keystore.
root_password='ghidra password'
# Path to Ghidra's cacerts file.
cacerts="${HOME}/ghidra-certs/cacerts"
# Path to Ghidra's svrAdmin.
svrAdmin="${HOME}/ghidra-current/server/svrAdmin"
### END CONFIGURATION ###
# Check for the root keystore and certificate, creating them if necessary.
if [[ ! -f ${root_keystore} && ! -f ${cacerts} ]]; then
# Create the keypair.
keytool -genkeypair \
-keyalg RSA \
-keystore "${root_keystore}" \
-storetype pkcs12 \
-storepass "${root_password}" \
-alias "${root_alias}" \
-dname "${root_dn}" \
-ext 'BC:critical=CA:true,pathlen:0' \
-ext 'KU:critical=keyCertSign'
# Export the CA cert.
keytool -exportcert \
-alias "${root_alias}" \
-keystore "${root_keystore}" \
-storepass "${root_password}" \
-storetype pkcs12 \
-file "${cacerts}"
echo "Add the root certificate to Ghidra's server.conf:"
echo "wrapper.java.additional.5=-Dghidra.cacerts=${cacerts}"
fi
if [[ ! -f ${root_keystore} ]]; then
echo "Missing ${root_keystore}" >&2
exit 1
fi
if [[ ! -f ${cacerts} ]]; then
echo "Missing ${cacerts}" >&2
exit 1
fi
# Create the keypair.
keytool -genkeypair \
-keyalg RSA \
-alias "${user_alias}" \
-dname "${user_dn}" \
-validity 1825 \
-keystore "${user_keystore}" \
-storetype pkcs12 \
-storepass "${user_password}"
# Import the CA cert.
keytool -importcert \
-alias "${root_alias}" \
-file "${cacerts}" \
-keystore "${user_keystore}" \
-storepass "${user_password}" \
-noprompt \
-trustcacerts
# Create a certificate signing request, create the certificate, and then import
# it back into the user's keystore.
keytool -certreq \
-keystore "${user_keystore}" \
-storepass "${user_password}" \
-alias "${user_alias}" \
-keyalg RSA |
keytool -gencert \
-keystore "${root_keystore}" \
-storepass "${root_password}" \
-alias "${root_alias}" \
-dname "${user_dn}" \
-ext 'BC:critical=CA:false' \
-ext 'KU:critical=digitalSignature,keyAgreement' \
-ext 'EKU:critical=clientAuth' |
keytool -importcert \
-keystore "${user_keystore}" \
-storepass "${user_password}" \
-alias "${user_alias}" \
-noprompt
# Delete the CA cert from the user keystore as it is no longer needed.
keytool -delete \
-alias "${root_alias}" \
-keystore "${user_keystore}" \
-storepass "${user_password}"
${svrAdmin} -add "${user_alias}"
${svrAdmin} -dn "${user_alias}" "${user_dn}"
echo "Give ${user_keystore} to the user with password '${user_password}'"

${HOME}/ghidra-current is a symlink to the currently active Ghidra directory. That is, I have several versions of Ghidra installed in ${HOME} and ghidra-current points to the one I'm using.

I'm keeping the cacerts and keystore outside of the Ghidra directory to make upgrading Ghidra easier. (I also keep the repositories directory outside of the Ghidra directory for the same reason.)

The directory for the keystore and cacerts should exist and the directory for the keystore should have permissions 0700. This isn't checked.

For this to work, you need to enable PKI authentication in server.conf by setting

wrapper.app.parameter.1=-a2
wrapper.app.parameter.2=${ghidra.repositories.dir}

and

wrapper.java.additional.5=-Dghidra.cacerts=/home/ghidra/ghidra-certs/cacerts

(or wherever you have configured the script for cacerts.

Running this script will create a new user with the specified user id (what Ghidra calls the sid) and produce a .p12 file. This file will need to be given to the user. The user can connect to the server in the Ghidra client by Edit > Set PKI Certificate... and selecting the .p12 certificate and entering the password ghidra (by default, this is configurable).

Note that I'm making no claims about the security of this setup. Nothing strikes me as obviously wrong or less secure than the password authentication option (-a0) and it seems to work.

An existing Ghidra server setup can be converted to use PKI by stopping the server, changing the server.conf, and then using this script for each existing user. You'll probably want to comment out the ${svrAdmin} -add "${user_alias}" line before running it on existing users to avoid trying to create a user twice.

Here are some (slightly outdated) notes about installing Ghidra Server on Ubuntu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment