Working with Self-Signed Certificates

For development it is sometimes useful to generate and use self-signed certificates and standup Broker Services that use TLS for SEMP calls.

Here is a set of examples of how to:

  • generate a self-signed certificate for a number of domains of your chosing, including localhost

  • add the certificate to the certificate authority bundle of your python installation

  • add the certificate to your keychain if you are using a Mac

Note

You can also switch certificates validation off in the modules. For details see parameters section in each module.

Generating the Certificate

Using the following example ssl config file, you can add as many domains as needed, including localhost:

[ req ]
default_bits       = 4096
distinguished_name = req_distinguished_name
req_extensions     = req_ext

[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
stateOrProvinceName         = State or Province Name (full name)
localityName                = Locality Name (eg, city)
organizationName            = Organization Name (eg, company)
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1   = localhost
DNS.2   = *.westeurope.cloudapp.azure.com

Note

Only use 1 wildcard in your domain. For example *.*.cloudapp.azure.com will not work.

The following script:

  • generates a private key in asc.key

  • generates a certificate in asc.crt

  • creates the PEM file combining the certificate & private key in asc.pem

#!/usr/bin/env bash
scriptDir=$(cd $(dirname "$0") && pwd);
scriptName=$(basename $(test -L "$0" && readlink "$0" || echo "$0"));

##############################################################################################################################
# Prepare

  privateKeyFile="$scriptDir/asc.key"
  certFile="$scriptDir/asc.crt"
  pemFile="$scriptDir/asc.pem"
  sslConfFile="$scriptDir/ssl.conf"

  subjectC="UK"
  subjectST="London"
  subjectL="London"
  subjectO="Solace Corporation"
  subjectCN="ansible-solace-collection"

##############################################################################################################################
# Run

echo ">>> Generating self-signed certificate ..."

  subject="/C=$subjectC/ST=$subjectST/L=$subjectL/O=$subjectO/CN=$subjectCN"
  openssl req \
    -newkey rsa:2048 -nodes -keyout "$privateKeyFile" \
    -x509 -days 3650 -out "$certFile.x" \
    -extensions req_ext \
    -config "$sslConfFile" \
    -subj "$subject"
  code=$?
  if [[ $code != 0 ]]; then echo " >>> XT_ERROR: generating certificate - $scriptName"; exit 1; fi

  echo "# Subject: $subject" > "$certFile"
  cat "$certFile.x" >> "$certFile"
  echo "# Subject: $subject" > "$pemFile"
  cat "$certFile.x" >> "$pemFile"
  cat "$privateKeyFile" >> "$pemFile"
  rm -f "$certFile.x"
  echo "    >>> generated pem file:"
  cat "$pemFile"
echo ">>> Success."

Python does not use the machine’s keychain or truststore but it’s own Certificate Authority Bundle file. The following script will:

  • find the CA Bundle file your python3 installation uses - python3 -m certifi

  • make a backup of it - *.original

  • append the new certificate asc.crt to the bundle file

#!/usr/bin/env bash
scriptDir=$(cd $(dirname "$0") && pwd);
scriptName=$(basename $(test -L "$0" && readlink "$0" || echo "$0"));

##############################################################################################################################
# Prepare

  certFile="$scriptDir/asc.crt"

##############################################################################################################################
# Run

echo ">>> Add new cert to python CA bundle ..."
  CA_CERT_BUNDLE_FILE=$(python3 -m certifi)
  originalCACertBundleFile="$CA_CERT_BUNDLE_FILE.original"
  if [ ! -f "$originalCACertBundleFile" ]; then
    cp "$CA_CERT_BUNDLE_FILE" "$originalCACertBundleFile"
    code=$?; if [[ $code != 0 ]]; then echo " >>> XT_ERROR: updating $CA_CERT_BUNDLE_FILE - $scriptName"; exit 1; fi
  fi
  # copy original and add to it
  cp "$originalCACertBundleFile" "$CA_CERT_BUNDLE_FILE"
  code=$?; if [[ $code != 0 ]]; then echo " >>> XT_ERROR: updating $CA_CERT_BUNDLE_FILE - $scriptName"; exit 1; fi
  cat "$certFile" >> "$CA_CERT_BUNDLE_FILE"
  code=$?; if [[ $code != 0 ]]; then echo " >>> XT_ERROR: updating $CA_CERT_BUNDLE_FILE - $scriptName"; exit 1; fi
echo ">>> Success."

Finally, if you are using a Mac, this script registers the new certificate with the keychain so you can access the Broker Service via your Browser using https:

#!/usr/bin/env bash
scriptDir=$(cd $(dirname "$0") && pwd);

##############################################################################################################################
# Prepare

  certFile="$scriptDir/asc.crt"
  subjectCN="ansible-solace-collection"

##############################################################################################################################
# Run

echo ">>> Register self-signed certificate mac ..."

  sudo security delete-certificate -c "$subjectCN"
  sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "$certFile"
  sudo security find-certificate -c "$subjectCN"

echo ">>> Success."

See also