Automic Workload Automation

 View Only
  • 1.  Enabling SSL for the JCP

    Posted Sep 20, 2021 08:19 AM
    Edited by Michael A. Lowry Sep 22, 2021 02:42 AM

    Introduction

    Below are instructions for enabling SSL-secured HTTP (HTTPS) for the Java Communications Process (JCP). These instructions are based on KB94420: How to implement HTTPS for JCP.

    The JCP requires a PKCS12 keystore containing a client certificate with the alias jetty. If the certificate is not self-signed, then an appropriate trust chain must be included in the keystore. The AWI must also be configured to trust the server certificate of the JCP.

    Self-signed certificate

    It's possible to create keystore with a self-signed certificate using a single keytool¹ command:

    $ keytool -keystore ./httpsRESTKeyFile -alias jetty -genkey -keyalg RSA -sigalg SHA256withRSA

    This will allow you to get up and running quickly, or to validate the HTTPS capability of the JCP on a test system. However, for production or customer-facing environments, it is important to use a certificate provided by a trusted certificate authority.

    Certificate from a certificate authority (CA)

    To use a certificate chain provided by a certificate authority, you will need to perform several additional steps. These are documented below.

    Description of file names

    File name

    Description

    wildcard_company_local.pfx

    Certificate chain provided by a certificate authority. This file will typically contain the client certificate for the node running the JCP, a private key, and one or more CA certificates from the relevant certificate authority - either a public CA or one operated by your company. This chain of trust guarantees that the client certificate is genuine.

    wildcard_company_local.key

    Private key extracted from certificate chain.

    wildcard_company_local.crt

    Client certificate extracted from certificate chain.

    wildcard_company_local.pkcs12

    Temporary keystore containing client certificate and associated private key.

    httpsRESTKeyFile

    Final PKCS12 keystore file for use by the Java Communications Process (JCP).

    Instructions

    1. Obtain a server certificate for the server where the JCP will run. The name of the server in the certificate can be either the server's DNS hostname or alias. The name in the certificate and the value of the hostname parameter in the ucsrv.ini file must match. The certificate will typically be provided in the form of a trust chain containing the server certificate plus a chain of parent CA certificates and

    2. Validate the contents of the PKCS12 trust chain provided by the certificate authority (CA). The file typically contains several parts, including a private key, a root CA certificate, one ormore intermediary CA certificates, and the client certificate for the host where you will run the Java Communications Process (JCP).
    $ openssl pkcs12 -in wildcard_company_local.pfx -info
    Enter Import Password: <Enter the password provided with your certificate>
    MAC Iteration 2000
    MAC verified OK
    PKCS7 Data
    Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2000
    Bag Attributes
        localKeyID: 01 00 00 00
        Microsoft CSP Name: Microsoft RSA SChannel Cryptographic Provider
      friendlyName: MyCompanyServerAuthentication
    Key Attributes
        X509v3 Key Usage: 10
    Enter PEM pass phrase: <For simplicity, use the same password>
    Verifying - Enter PEM pass phrase: <Re-enter the same password again>
    -----BEGIN ENCRYPTED PRIVATE KEY-----
    ...
    -----END ENCRYPTED PRIVATE KEY-----
    PKCS7 Data
    Certificate bag
    Bag Attributes: <Empty Attributes>
    subject=/C=US/O=MyCompany/CN=MyCompany Root CA
    issuer=/C=US/O=MyCompany/CN=MyCompany Root CA
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    Certificate bag
    Bag Attributes: <Empty Attributes>
    subject=/C=US/O=MyCompany/CN=MyCompany Intermediary CA
    issuer=/C=US/O=MyCompany/CN=MyCompany Root CA
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    Certificate bag
    Bag Attributes
        localKeyID: 01 00 00 00
    subject=/C=US/O=MyCompany/CN=ae-test.mycompany.com
    issuer=/C=US/O=MyCompany/CN=MyCompany Intermediary CA
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----

    3. Extract the private key.
    $ openssl pkcs12 -in ./wildcard_company_local.pfx -nocerts -out ./wildcard_company_local.key
    Enter Import Password:
    <Enter the password provided with your certificate>
    MAC verified OK
    Enter PEM pass phrase: <For simplicity, use the same password>
    Verifying - Enter PEM pass phrase: <Re-enter the same password again>

    4. Extract the client certificate.
    $ openssl pkcs12 -in ./wildcard_company_local.pfx -clcerts -nokeys -out ./wildcard_company_local.crt
    Enter Import Password: <Enter the password provided with your certificate>
    MAC verified OK

    5. Combine the private key and certificate into a single file.
    $ openssl pkcs12 -inkey ./wildcard_company_local.key -in ./wildcard_company_local.crt -export -out ./wildcard_company_local.pkcs12
    Enter pass phrase for ./wildcard_company_local_key: <Enter the same password as above>
    Enter Export Password: <Use the same password as above>
    Verifying - Enter Export Password: <Re-enter the same password as above>

    6. Convert the combined key/certificate file to a PKCS12 keystore using the keytool¹ program.
    $ keytool -importkeystore -srckeystore ./wildcard_company_local.pkcs12 -destkeystore ./httpsRESTKeyFile -srcstoretype PKCS12 -alias "1" -destalias "jetty"
    Importing keystore ./wildcard_company_local.pkcs12 to ./httpsRESTKeyFile...
    Enter destination keystore password: <Enter the same password as above>
    Enter source keystore password: <Enter the same password as above>
    Existing entry alias 1 exists, overwrite? [no]: yes

    7. List out the keystore contents to confirm that all of the parts are there.
    $ keytool -list -v -keystore ./httpsRESTKeyFile
    Enter keystore password: <Enter the same password as above>
    Keystore type: PKCS12
    Keystore provider: SunJSSE

    Your keystore contains 1 entry

    Alias name: jetty
    Creation date: Sep 1, 2021
    Entry type: PrivateKeyEntry
    Certificate chain length: 1
    Certificate[1]:
    ...

    Under the heading Extensions, you should typically see sections labeled AuthorityInfoAccess, AuthorityKeyIdentifier, CertificatePolicies, ExtendedKeyUsages, KeyUsage, SubjectAlternativeName, and SubjectKeyIdentifier.

    8. Copy your company's CA certificates file (cacerts) the AWI installation directory and add two Java system properties to JAVA_OPTS before starting the AWI.

    -Duser.timezone=Europe/Zurich -Djavax.net.ssl.trustStore=$PWD/cacerts

    The first system property just tells the AWI what time zone to use, and this should be your local time zone. The second system property tells the AWI where to find the trust store containing the CA certificates. This will make the AWI trust the certificate authority. This in turn will make the AWI trust the JCP's server certificate, because its trust chain is based the parent CAs.

    Note

    1. To create a PKCS12 keystore using the keytool program, it may be necessary to first set keystore.type to pkcs12 in the Java security properties file $JAVA_HOME/../lib/security/java.security. See the Oracle documentation page for keytool for more information.

     


    Revision history

    2021.09.20
    Added instructions for setting hostname parameter in ucsrv.ini file, and instructions for installing CA certificates for the AWI.
    2021.09.01
    Initial version.



  • 2.  RE: Enabling SSL for the JCP

    Posted Mar 10, 2022 03:08 PM
    Edited by Michael A. Lowry Mar 10, 2022 03:21 PM
    I wrote a script to automate some of these steps. It works with the certificate/trust chain files provided by our CA. Your mileage may vary.

    #!/bin/sh
    #
    # Make_Key_Store.sh
    # Make a PKCS12 key store for the Java Communications Process of the Automation Engine.
    #
    # Author
    # Michael A. Lowry <michael.lowry@gmail.com>
    #
    # Version history
    # 0.1   MAL     2021.09.02      Initial version
    #
    
    shopt -s extglob
    log_level="verbose"
    SCRIPT_NAME=$(basename $0)
    SCRIPT_VERSION="0.1"
    echo "$SCRIPT_NAME v$SCRIPT_VERSION"
    usage () {
    cat <<EOF
    
    NAME
      $SCRIPT_NAME
    
    SYNOPSIS
      Create a PKCS12 key store for the Java Communications Process (JCP)
    
    DESCRIPTION
        $SCRIPT_NAME <input_cert_chain> <password> <Output_Key_Store>
    
      Print this usage stagement
        $SCRIPT_NAME
    
    OPTIONS
      <input_cert_chain>
            The PKCS#12 certificate chain provided by the Certificate Authority (CA).
    
      <password>
            The password used to encrypt the private key in the certificate chain.
            This password will also be used as the key store passowrd.
    
      <Output_Key_Store>
            The name of the key store file to write.
    
    EXAMPLE
     $SCRIPT_NAME certificate_chain.p12 CDJFJ3kdkj3dSPn keystore
    
    EOF
            exit 1
    }
    
    if [[ $# -ne 3 ]]; then usage; fi
    Java_Security_Config="${JAVA_ROOT}/lib/security/java.security"
    Keystore_Type=$(awk -F= '$1=="keystore.type" {print $2}' "${Java_Security_Config}" | dos2unix )
    echo
    echo
    echo "Java security config : ${Java_Security_Config}"
    echo "Keystore type: ${Keystore_Type}"
    echo
    echo
    if [[ "${Keystore_Type}" != "pkcs12" ]]; then
            echo "keystore.type in ${Java_Security_Config} is set to ${Keystore_Type}. It must be set to pkcs12."
            exit 1
    fi
    Input_Cert_Chain=$1
    Password=$2
    Output_Key_Store=$3
    Temp_Private_Key=./Temp_Private_Key
    Temp_Certificate=./Temp_Certificate
    Temp_Cert_Chain=./Temp_Cert_Chain
    if [[ ! -f ${Input_Cert_Chain} ]]; then echo "Certificate chain does not exist or is not readable: ${Input_Cert_Chain}"; exit 1; fi
    openssl pkcs12 -in ${Input_Cert_Chain} -nocerts -out ${Temp_Private_Key} -passin pass:${Password} -passout pass:${Password}
    openssl pkcs12 -in ${Input_Cert_Chain} -clcerts -nokeys -out ${Temp_Certificate} -passin pass:${Password} -passout pass:${Password}
    openssl pkcs12 -inkey ${Temp_Private_Key} -in ${Temp_Certificate} -export -out ${Temp_Cert_Chain} -passin pass:${Password} -passout pass:${Password}
    keytool -importkeystore -srckeystore ${Temp_Cert_Chain} -destkeystore ${Output_Key_Store} -srcstoretype PKCS12 -alias "1" -destalias "jetty" -srcstorepass ${Password} -deststorepass ${Password}
    RC=$?
    if [[ $RC -eq 0 ]]; then rm  ${Temp_Private_Key} ${Temp_Certificate} ${Temp_Cert_Chain}; fi​

    The script uses the same password for the created keystore as for the input certificate file.