Table of Contents:
- Prerequisites
- Understanding the basics of SSL/TLS
- Notes
- Server-Side Config
- Create private and public key
- Get certificate signed by a Certificate Authority
- Import Cert into the Tomcat Java keystore
- Configure PASOE to use the keystore
- Client-Side Config and test
- Import cert into OpenEdge
- Test connection
Prerequisites:
- Basic knowledge of SSL / TLS and certificates is required.
- Run the commands below in a ‘Proenv’ environment.
- On Windows replace <DLC> with %DLC% .
- On UNIX / Linux replace <DLC> with $DLC and back slashes with forward slashes.
- Replace <CATALINA_BASE> with the path of the PASOE instance.
- Use ‘pasman instances’ to list all PASOE instances and the path to their <CATALINA_BASE> on the system.
Access via HTTPS is dependent on having an SSL/TLS Server Certificate:
- <CATALINA_BASE>\conf\tomcat-keystore.p12 - The default PASOE instance keystore file which uses a PKCS12 type storage format, it contains 2 aliases for testing and is maintained using the Java Keytool or SSLC utility.
- <CATALINA_BASE>\conf\tomcat-certstore.jks - The certificate trust store file for intermediate/root CA certificates, which uses the default JAVA distribution file format JKS.
- <CATALINA_BASE>\conf\server.xml - PASOE TLS/SSL is controlled by Tomcat connectors (configured via catalina.properties).
Note 1: If not using a certificate with subject alternative name (SAN), the CN on the certificate must match the machines hostname, otherwise error 9318 with error code -55 will be returned from an ABL client.
Note 2: The following instructions ultimately write to the tomcat-keystore.p12. This is the default keystore file embedded within the <CATALINA_BASE>\conf\server.xml which PASOE (e.g. Tomcat) uses to store the certificate information. If a file other than tomcat-keystore.p12 is to be used, the <CATALINA_BASE>\conf\server.xml must be updated and the following reference should be changed to reflect the correct file:
certificateKeystoreFile="${catalina.base}/conf/<alternate keystore filename here>"
References to "tomcat-keystore.p12" in the instructions below will need to be adjusted to reflect the alternate name of the keystore file.
Server-Side Config:
Note: If the environment already has a signed certificate use Option B instead.
Option A | I need to acquire a new signed certificate for production
A1. Create the following directory: <DLC>\keys\requests if it doesn't exist.
A2. Configure Subject Alternative Name (SAN) entries for the certificate:
- Make a backup of <DLC>\keys\policy\pscpki.cnf
- Remove the "Read-only" attribute of the file then open <DLC>\keys\policy\pscpki.cnf in a text editor
- Add the req_extensions property to the [ req ] section. For example:
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
req_extensions = v3_req
- Add a [ v3_req ] and [alt_names] section between the [ req_attributes ] and [ x509v3_extensions ] sections. For example:
[ req_attributes ]
#challengePassword = A challenge password
#challengePassword_min = 4
#challengePassword_max = 20
#unstructuredName = An optional company name
certs = $ENV::DLC/certs
default_md = sha256
default_bits = 2048
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = <full name of the first server hosting the service as it will be used in the browser>
DNS.2 = <full name of the second server hosting the service as it will be used in the browser>
#An example might be as follows:
#DNS.1 = myrestserver1.domain.com
#DNS.2 = myrestserver2.domain.com
#DNS.3 = myrestserver3.domain.com
#DNS.4 = myrestserver4.domain.com
[ x509v3_extensions ]
basicConstraints=critical,CA:FALSE,pathlen:0
#keyUsage=serverAuth
Note: The use of the Common Name (CN) field within a certificate has been deprecated since the year 2000 in favor of the subjectAltName field (Subject Alternative Name). Refer to
RFC 2818, chapter 3.1, where the following is stated:
"If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Although the use of the Common Name is existing practice, it is deprecated and Certification Authorities are encouraged to use the dNSName instead."
A3. Generate the private (.pk1) and public (.pk10) keys using the OpenEdge pkiutil utility:
- Within a Proenv session, go to <DLC>\keys\requests .
- Run the following command to generate a key pair which includes the Certificate Signing Request (CSR):
pkiutil -keysize 2048 -newreq <certificate alias name>
The "
certificate alias name" is used to name the server certificate on the filesystem (e.g. <DLC>\keys\MyAlias.pem).
Example:
pkiutil -keysize 2048 -newreq myservernameNote: The pkiutil tool included in OpenEdge 11.5 through OpenEdge 11.7.4 has a keysize limitation of 2048 bits. To make a private key with a keysize greater than 2048 bits, please refer to the following KB article:
pkiutil prevents the creation of 4096 bit private keys
- When prompted, choose a password / passphrase and take note of it. After you enter and verify the passphrase, the private key with a .pk1 extension will be generated in the current directory (e.g. myservername.pk1)
The pkiutil utility will issue a prompt asking for specific information that will be incorporated into the CSR. For example:
-----
Country Name (2 letter code) [US]:<Country>
State or Province Name (full name) []:<State>
Locality Name (eg, city) []:<City>
Organization Name (eg, company) []: <Company name>
Organizational Unit Name (eg, section) []:< Business unit>
Server DNS name []:<Hostname>
Once the required information is provided, a file with a .pk10 extension will be generated in the current directory (e.g. myservername.pk10). This is also referred to as the CSR.
A4. Provide the .pk10 file (e.g. the CSR) generated in the above steps to the Certificate Authority (CA) when requesting the signed certificate.
Note: For testing only, a self-signed certificate can be created using the pk10 and pk1 files created above, this cert should NOT be used in production.
sslc x509 -req -days 365 -in <full path to file>.pk10 -signkey <full path to file>.pk1 -out cert.crt
A5. After the signed certificate (.cer , .crt or .pem) is received from the CA (or self -signed), use the pkiutil tool with the -import option to import the certificate into the OpenEdge keystore:
- Run the following command:
pkiutil -import <certificate alias name> <DLC>\keys\requests\<signed certificate filename>
Example: pkiutil -import myservername C:\DLC\keys\requests\SignedByCA.pem
Output similar to the following will be displayed:
Importing private key alias <certificate alias name>:
Importing certificate file <signed certificate filename>
This will generate a <certificate alias name>.pem file under <DLC>\keys (e.g. myservername.pem).
A6. Make sure that the <DLC>\keys\<certificate alias name>.pem file contains the complete certificate chain, otherwise OCSP Stapling will not work:
- The <DLC>\keys\<certificate alias name>.pem file will contain the private and signed certificate, something similar to the following:
-----BEGIN RSA PRIVATE KEY-----
<content of private key>
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
<content of signed server certificate>
-----END CERTIFICATE-----
- Add the intermediate and root certificates used by the Certificate Authority. So the <DLC>\keys\<certificate alias name>.pem file should contain something similar to the following:
-----BEGIN RSA PRIVATE KEY-----
<content of private key>
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
<content of signed server certificate>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<content of intermediate certificate>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<content of root certificate>
-----END CERTIFICATE-----
If needed ask the Certificate Authority for the intermediate certificates (if applicable) and the root certificate in the PEM format.
The current certificate chain within the <DLC>\keys\<certificate alias name>.pem file can be verified by running the following command within a Proenv session:
sslc crl2pkcs7 -nocrl -certfile <DLC>\keys\<certificate alias name>.pem | sslc pkcs7 -print_certs
Example: sslc crl2pkcs7 -nocrl -certfile C:\DLC\keys\myservername.pem | sslc pkcs7 -print_certs
This will display the subject, issuer and the content (in PEM format) of each certificate in the <DLC>\keys\<certificate alias name>.pem file (so the certificate chain). For example:
subject=...
issuer=...
-----BEGIN CERTIFICATE-----
<content of signed server certificate>
-----END CERTIFICATE-----
subject=...
issuer=...
-----BEGIN CERTIFICATE-----
<content of intermediate certificate>
-----END CERTIFICATE-----
subject=...
issuer=...
-----BEGIN CERTIFICATE-----
<content of root certificate>
-----END CERTIFICATE-----
A7. (Windows Only) set the RANDFILE variable so the 'random state' file can be created:
set RANDFILE=%DLC%\keys\.rnd
A8. Create a new PASOE keystore using the signed certificate:
- Run the following command:
sslc pkcs12 -export -in <DLC>/keys/<certificate alias name>.pem -out tomcat-keystore.p12 -name <signed certificate alias name>
Example: sslc pkcs12 -export -in <DLC>/keys/myservername.pem -out tomcat-keystore.p12 -name pasoecert
This will generate a keystore called "tomcat-keystore.p12" in the current directory. The <signed certificate alias name> can be any given name, it is an alias for the signed certificate in the "tomcat-keystore.p12" keystore.
Note 1: Note down the <signed certificate alias name>, because this is needed later on for the following property in the <CATALINA_BASE>\conf\catalina.properties file: psc.as.https.keyalias .
Note 2: There will be a prompt to create an “export” password. Remember what is entered for the "export" password, because it is needed later on for the following property in the <CATALINA_BASE>\conf\catalina.properties file: psc.as.https.keypass .
Option B | I already have a signed certificate
B1. If the certificate is not in a PEM format, convert it to PEM in a Proenv session.
- In case of a certificate file in the DER format, use the following command:
sslc x509 -in mycert.crt -out mycert.pem -outform PEM
- In the case of a DER encoded .p7b file use the following command:
sslc pkcs7 -in <filename>.p7b -inform DER -print_certs -outform PEM -out <filename>.pem
- In the case of a PEM encoded .p7b file use the following command:
sslc pkcs7 -in <filename>.p7b -inform PEM -print_certs -outform PEM -out <filename>.pem
- Open the .pem file and delete everything outside the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- content and save it. So the content should look similar to the following:
-----BEGIN CERTIFICATE-----
<certificate A>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<certificate B>
-----END CERTIFICATE-----
Note: It is possible that multiple certificates make up the certificate chain. If the certificates are in PEM format, they need to be combined. PEM certificates are ASCII and can be combined in a text editor of your choice. Each certificate starts with -----BEGIN CERTIFICATE----- and ends with -----END CERTIFICATE-----. Be mindful that you do not lose any of the dashes otherwise the certificate will be invalid. Combine one certificate after the other into a text file, having the -----END CERTIFICATE----- of one certificate immediately followed by the -----BEGIN CERTIFICATE----- of the next certificate. Save this file with a meaningful name.
B2. (Windows Only) set the RANDFILE variable so the 'random state' file can be created:
set RANDFILE=%DLC%\keys\.rnd
B3. Generate the keystore by using the PEM and private key for the certificate:
- Make sure the PEM and private key are located under the current directory.
- Run the following command from within a Proenv session:
sslc pkcs12 -export -inkey <private key> -in <signed public key file name>.pem -out tomcat-keystore.p12 -name <alias name>
Example: sslc pkcs12 -export -inkey private.key -in SignedByCA.pem -out tomcat-keystore.p12 -name pasoecert
This will generate a keystore called "tomcat-keystore.p12" in the current directory. The
<signed certificate alias name> can be any given name, it is an alias for the signed certificate in the "tomcat-keystore.p12" keystore.
Note 1: Note down the alias name, because this is needed later on for the following property in the <CATALINA_BASE>\conf\catalina.properties file:
psc.as.https.keyalias .
Note 2: There will be a prompt to create an “export” password. Remember what is entered for the "export" password, because it is needed later on for the following property in the <CATALINA_BASE>\conf\catalina.properties file:
psc.as.https.keypass .
Note 3: If this step fails with error "
Can't open key file for reading, no such file or directory", please refer to KB article
Can't open key file for reading, no such file or directory when deploying SSL certificates .
Options A & B continuation:
1. Verify the content of the newly created keystore and that the required certificate and hierarchy are correct by using one of these utilities:
- Using the Java Keytool utility:
<Path to JDK>\bin\keytool -storetype PKCS12 -list -keystore tomcat-keystore.p12
- Using the SSLC utility within a Proenv session:
sslc pkcs12 -info -in tomcat-keystore.p12
2. Rename the default PASOE instance keystore (<CATALINA_BASE>\conf\tomcat-keystore.p12) to tomcat-keystore.p12.org.
3. Move the newly created keystore (tomcat-keystore.p12) to <CATALINA_BASE>\conf .
4. Configure the PASOE instance to use the new alias and keystore password by updating <CATALINA_BASE>\conf\catalina.properties .
<CATALINA_BASE>\bin\tcman config psc.as.https.keyalias=<signed certificate alias name>
<CATALINA_BASE>\bin\tcman config psc.as.https.keypass=<export password>
5. Restart the PASOE instance for the changes to take effect.
Client-Side Config:
1. The clients that will be connecting to the PASOE instance via HTTPS will require the root/intermediate CA's certificates in order to validate the signed certificate. If the client is an ABL client use the "certutil" utility to import the certificate into the OpenEdge truststore (e.g. <DLC>\certs):
certutil -import <path to certificate>
Example 1: certutil -import CARootCert.pem
Example 2: certutil -format DER -import CARootCert.cer
Third-party clients like web browsers usually use the OS specific certificate truststore or their own truststore. Well-known CA certificates are usually already included in these truststores.
2. Sample ABL code to test the connection:
DEFINE VARIABLE hAppSrv AS HANDLE NO-UNDO.
DEFINE VARIABLE ret AS LOGICAL NO-UNDO.
CREATE SERVER hAppSrv.
ret = hAppSrv:CONNECT('-sessionModel "Session-free" -URL "https://myrestserver1.domain.com:8811/apsv"').
IF NOT ret THEN DO:
DELETE OBJECT hAppSrv NO-ERROR.
RETURN ERROR "Failed to connect to the PASOE instance via HTTPS " + RETURN-VALUE.
END.
ELSE DO:
message "Connection successful" view-as alert-box.
END.
ret = hAppSrv:DISCONNECT().
DELETE OBJECT hAppSrv NO-ERROR.
For a third party client like a web browser, access the application via the HTTPS URL. For example:
https://localhost:8811/apsv
https://myrestserver1.domain.com:8811/TestWebApp/rest/RESTService/GetCustomers