Mutual Authentication
Introduction
The Mutual Authentication feature allows the FNZ Studio Platform to communicate securely with another server. It enables HTTPS / SSL connections between FNZ Studio as a client and a remote service. For example, a secure connection may be required when retrieving or posting data to a remote server, or consuming a SOAP or REST service.
The connection can be authenticated either by the client (Server Authentication) or by both parties (Client/Mutual Authentication). The object being authenticated – not the authenticator – determines the type of authentication.
Mutual Authentication uses the Key Store, which contains private keys for client/mutual authentication, and the Trust Store, which contains certificates for server authentication.
The following Script Functions are available for Mutual Authentication (see details in section Script Functions):
Note that FNZ Studio also provides a UI module ( System Configuration > Passwords, Keys & Certificates), which allows performing some of these actions. See Secrets Management Framework.
AddClientKeyAlias()– Adds runtime (not configuration) SSL-Host-to-Key-Alias mappingsRemoveClientKeyAlias()– Removes runtime (not configuration) SSL-Host-to-Key-Alias mappingsAddPrivateKey()– Adds a client key to the Key StoreRemovePrivateKey()– Removes a client key from the Key StoreAddTrustedCertificate()– Adds a certificate for a service to the Trust StoreRetrieveTrustedCertificate()– Retrieves a certificate from the Trust Store so that it can be exportedRemoveTrustedCertificate()– Removes a certificate from the Trust StoreUseAlias()– Overrides the configuration for a host's standard aliasRemoveSpecifiedAlias()– Removes an alias currently used to override the standard configurationHTTPGET()– Sends an HTTP Get request to the specified URL and supports SSLHTTPPOST()– Sends an HTTP Post request to the specified URL and supports adding SSL
The following schema shows an example of server authentication. The client initiates a connection with the server, which then supplies its certificate to the client for authentication. Once the server's authenticity has been verified, the connection is established and HTTP communication can take place over the secured connection:
                                                    
                                                
The following schema shows an example of Client/Mutual Authentication. The client sends a connection request and the server sends back its certificate, but also requests the client's certificate. The client verifies the authenticity of the server certificate and then sends back its own certificate, which the server then verifies. Once each party has verified the validity of the other party's certificate, the secure connection is established and HTTP communication can take place over the secure connection:
                                                    
                                                
Configuration
Server Authentication
If you are using server authentication only, configuration may not be necessary. If the server has a certificate supplied by a reputable certificate authority (CA) known to Java, no specific setting is required.
If the CA is not known, add a certificate for it using the AddTrustedCertificate Script Function or any of the certificates in the chain for the server.
If you have several servers which all have certificates supplied by the same CA, installing the CA certificate automatically builds the trust chain for all of them. It is not necessary to import them all.
In the case of self-signed certificates, it is possible to create a CA certificate used for creating the other self-signed certificates.
Client Authentication
The server authentication configuration described above (server certificates and Trust Store) also applies to client authentication.
For client authentication, it is additionally necessary to:
- Add your private key to the Key Store and give that key an alias.
 - Configure FNZ Studio to associate this alias and the host of the service you intend to use:
- Go to System Configuration > Configuration Properties  and locate the 
nm.security.ssl.serverAliasMappingsproperty. - Create a list of server-to-alias associations as the value of this property. The host is separated from the alias by a colon and each entry is separated by a semicolon.
Example: 
dev.numcom.local:cerclient;test.numcom.local:certwo 
 - Go to System Configuration > Configuration Properties  and locate the 
 
Script Functions
Add Client Key Alias
The AddClientKeyAlias Script Function adds a runtime host-to-alias mapping. This is not saved as a configuration.
AddClientKeyAlias($hostname, $alias)
                                                    | Parameter | Description | 
|---|---|
$hostname (String) | 
                                                            Name of the host you want to associate to an alias | 
$alias (String) | 
                                                            Alias to be associated with the host | 
Example:
String $hostname := 'localhost';
String $alias := 'tester';
AddClientKeyAlias($hostname, $alias);
                                                    Add Private Key
The AddPrivateKey Script Function loads and stores a private key in the Key Store.
AddPrivateKey($alias, $keyfilepath, $password)
                                                    | Parameter | Description | 
|---|---|
$alias (String) | 
                                                            Alias with which the new key must be associated in the Key Store | 
$keyfilepath (String) | 
                                                            Path to the key file in PFX format. The file must previously have been uploaded to the data home directory by an administrator. | 
$password (String) | 
                                                            Password to extract the key from the PFX file | 
| Return value | Description | 
|---|---|
| Boolean | 'true' if the operation succeeds, 'false' if it fails | 
Example:
String $alias := 'tester';
String $keyfilepath := 'data/keys/mykey.pfx';
String $password := 'password';
AddPrivateKey($alias, $keyfilepath, $password);
                                                    Add Trusted Certificate
The AddTrustedCertificate Script Function loads and stores server or Certificate Authority certificates in the Trust Store. See Chapter 4, "Certificate Retrieval" for more information on retrieving certificates.
AddTrustedCertificate($alias, $certificatefilepath)
                                                    | Parameter | Description | 
|---|---|
$alias (String) | 
                                                            Alias with which this certificate must be associated in the Trust Store | 
$certificatefilepath (String) | 
                                                            Path the certificate file in CER format (base64-encoded serialized certificate). This file must have been uploaded to the data home directory by an administrator. | 
| Return value | Description | 
|---|---|
| Boolean | 'true' if the operation succeeds, 'false' if it fails | 
Example:
String $alias := 'service1';
String $certificatefilepath := 'data/certificates/mycert.cer';
AddTrustedCertificate($alias, $certificatefilepath);
                                                    Remove Client Key Alias
The RemoveClientKeyAlias Script Function removes a runtime host-to-alias mapping. This is not saved as a configuration.
RemoveClientKeyAlias($alias)
                                                    | Parameter | Description | 
|---|---|
$alias (String) | 
                                                            Associated alias to be removed | 
Return value: (Boolean) 'true' if the operation succeeds, 'false' if it fails .
Example:
String $alias := 'tester';
RemoveClientKeyAlias($alias);
                                                    Remove Private Key
The RemovePrivateKey Script Function removes a private key from the Key Store.
RemovePrivateKey($alias)
                                                    | Parameter | Description | 
|---|---|
$alias (String) | 
                                                            Alias associated with the key to be removed | 
Return value: (Boolean) 'true' if the operation succeeds, 'false' if it fails .
String $alias := 'tester';
RemovePrivateKey($alias);
                                                    Remove SSL Alias
The RemoveSSLAlias Script Function removes an alias that overrides the default alias for a service. It does not take any parameters.
RemoveSSLAlias()
                                                    Parameters: None
| Return value | Description | 
|---|---|
| Boolean | 'true' if the operation succeeds, 'false' if it fails | 
Remove Trusted Certificate
The RemoveTrustedCertificate Script Function removes a certificate from the Trust Store.
RemoveTrustedCertificate($alias)
                                                    | Parameter | Description | 
|---|---|
$alias (String) | 
                                                            Alias associated with the certificate to be removed | 
| Return value | Description | 
|---|---|
| Boolean | 'true' if the operation succeeds, 'false' if it fails | 
Example:
String $alias := 'service1';
RemoveTrustedCertificate($alias);
                                                    Retrieve Trusted Certificate
The RetrieveTrustedCertificate Script Function exports a certificate from the Trust Store.
RetrieveTrustedCertificate($alias)
                                                    | Parameter | Description | 
|---|---|
$alias (String) | 
                                                            Alias associated with the certificate you want to export | 
| Return value | Description | 
|---|---|
| String | A base64 encoded String containing the certificate that can be serialized directly to disk to create a certificate file. | 
Example:
String $alias := 'service1';
String $fileContent := RetrieveTrustedCertificate($alias);
LocalFile $file := NewObject('LocalFile', 'certs/service1.cer');
$file.writeText($file, 'ISO-8859-1');
                                                    Use SSL Alias
The UseSSLAlias Script Function sets an alias that overrides the default alias for a service
UseSSLAlias($alias)
                                                    | Parameter | Description | 
|---|---|
$alias (String) | 
                                                            Alias to be used to override | 
Return value: None
Example:
String $alias := 'anotherAlias';
UseSSLAlias($alias);
                                                    HTTP GET
The HTTPGET Script Function sends an HTTP Get request to the specified URL.
HTTPGET($url, $file, $username, $password, $timeout, $proxyHost)
                                                    | Parameter | Description | 
|---|---|
$url (String) | 
                                                            URL of the request.nExample: 'http://www.appway.com' | 
                                                        
$file (String) | 
                                                            File path to save the response. If the path refers to an existing directory, the HTTP header "Content-Disposition" determines the file's name. If no path is specified, the HTTP response body is not saved. A relative path is considered relative to the Data Home.nExample: 'work/tmp/download.tmp' | 
                                                        
$username (String) | 
                                                            Username required for authentication.nExample: 'tester' | 
                                                        
$password (String) | 
                                                            Password to be used for authentication.nExample: 'password' | 
                                                        
$timeout (Integer) | 
                                                            Timeout in seconds (default: 30).nExample: 120 | 
                                                        
$proxyHost (String) | 
                                                            Host name or IP address of the proxy server.nExample: 'proxy.domain.local' | 
                                                        
$proxyPort (Integer, optional) | 
                                                            Proxy server port (default: 8008).nExample: 8008 | 
                                                        
$proxyUsername (String, optional) | 
                                                            Username for proxy server.nExample: 'username' | 
                                                        
$proxyPassword (String, optional) | 
                                                            Password for proxy server.nExample: 'password' | 
                                                        
$certificateAlias (String, optional) | 
                                                            Key Store alias to be used for SSL authentication.nExample: 'tester' | 
                                                        
| Return value | Description | 
|---|---|
| Integer | HTTP status code of the response, for example:n200 okn304 not modifiedn401 unauthorizedn403 forbiddenn404 not foundn500 internal server error.nA negative result means an non-HTTP error: | 
- 1 unknown I/O error
 - 2 malformed URL
 - 3 unknown host
 - 4 socket timeout
 - 10 unknown socket error
 - 11 connection error
 - 12 no route to host
 - 13 port unreachable
 - 14 SSL client authentication failed
 - 15 Security Issue accessing KeyStores
 
Example:
String $url := 'http://localhost:8080/myservice';
String $file := 'work/file.dat';
String $username := 'username';
String $password := 'password';
Integer $timeout := 120;
String $proxyHost := 'proxy';
Integer $proxyPort := 8008;
String $proxyUser := 'pass';
String $proxyPassword := 'username';
String $certificateAlias := 'password';
Integer $statusCode := HTTPGET($url, $file, $username, $password, $timeout, $proxyHost, $proxyPort, $proxyUser, $proxyPassword, $certificateAlias);
HTTP POST
The HTTPPOST Script Function sends an HTTP Post request to the specified URL.
HTTPPOST($url)
| Parameter | Description | 
|---|---|
$url (String) | URL of the request.nExample: 'http://www.appway.com' | 
$data (Named Any, optional) | POST data as named collection. nSet the key PostBodyText to a String or the key PostBodyFile to a file path in order to specify the POST request body manually (all other keys will be ignored in this case). nTo set Request Headers, use the key PostRequestHeaders (Named String).n You can also include HttpFileUpload objects as values to create multipart mime uploads.nExample:n HttpFileUpload $upload := new HttpFileUpload;n$upload.contentType := 'application/json';n$upload.filePath := 'work/myJsonFile.json';nNamed Any $data := NewNamed(Any);n$data.setElement('myJsonFile', $upload); | 
$file (String, optional) | File path to save the response. If the path refers to an existing directory, the HTTP header "Content-Disposition" determines the file name. If no path is specified, the HTTP response body is not saved. A relative path is considered relative to the Data Home.nExample: 'work/tmp/download.tmp' | 
$username (String, optional) | Username required for authentication.nExample: 'tester' | 
$password (String, optional) | Password to be used for authentication.nExample: 'password' | 
$timeout (Integer, optional) | Timeout in seconds (default: 30).nExample: 120 | 
$proxyHost (String, optional) | Host name or IP address of the proxy server.nExample: 'proxy.domain.local' | 
$proxyPort (Integer, optional) | Proxy server port (default: 8008).nExample: 8008 | 
$proxyUsername (String, optional) | Username for the proxy server.nExample: 'username' | 
$proxyPassword (String, optional) | Password for the proxy server.nExample: 'password' | 
$certificateAlias (String, optional) | Key Store alias to be used for SSL authentication.nExample: 'tester' | 
| Return value | Description | 
|---|---|
| Integer | HTTP status code of the response, for example: | 
- 200 ok
 - 304 not modified
 - 401 unauthorized
 - 403 forbidden
 - 404 not found
 - 500 internal server error.
 
- 1 unknown I/O error
 - 2 malformed URL
 - 3 unknown host
 - 4 socket timeout
 - 10 unknown socket error
 - 11 connection error
 - 12 no route to host
 - 13 port unreachable
 - 14 SSL client authentication failed
 - 15 Security Issue accessing KeyStores
 
Example:
String $url := 'http://localhost:8080/myservice';
Named Any $data := {}:Any;
String $file := 'work/file.dat';
String $username := 'username';
String $password := 'password';
Integer $timeout := 120;
String $proxyHost := 'proxy';
Integer $proxyPort := 8008;
String $proxyUser := 'pass';
String $proxyPassword := 'username';
String $certificateAlias := 'password';
Integer $statusCode := HTTPPOST($url, $data, $file, $username, $password, $timeout, $proxyHost, $proxyPort, $proxyUser, $proxyPassword, $certificateAlias);
Certificate Retrieval
Before importing a certificate into the Trust Store, you need to retrieve it from the remote server. The procedure is very similar for all browsers; this chapter is based on a Firefox.
Enter the URL of the server. If its certificate is not from a known Certificate Authority, your browser displays a warning. Expand "I understand the risks" and click on "Add exceptions…".

Figure 5: Expanded untrusted connection
View the certificate (see the example certificate below).

Figure 6: Add exception

Figure 7: View certificate
After closing the window and confirming the security exception, go to Preferences > Advanced > Certificates > View Certificates. From here, you can either export a CA certificate or a certificate for a specific server. Select a certificate and export it to your local disk.

Figure 8: Authorities

Figure 9: Servers
Save the exported certificate file on a server accessible to FNZ Studio (ask a system administrator). The path to this file can be used as a parameter for the AddTrustedCertificate Script Function.