Configuring IceSSL
After installing IceSSL, an application typically needs to define a handful of additional properties to configure settings such as the location of certificate and key files. This page provides an introduction to configuring the plug-in for each of the supported language mappings.
On this page:
Configuring IceSSL for C++ and .NET on Windows
IceSSL for .NET and C++ supports loading certificates, keys, and trusted CA certificates from regular files. You can also make use of Windows certificate stores.
The ability to load trusted CA certificates from a file in .NET is a new feature added in Ice 3.6.
Using Certificate Files
Our first example demonstrates how to configure IceSSL with certificate files:
# For .NET: Ice.Plugin.IceSSL=IceSSL.dll:IceSSL.PluginFactory # For C++: Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.DefaultDir=/opt/certs IceSSL.CAs=cacert.pem IceSSL.CertFile=cert.pfx IceSSL.Password=password
Notice that the value for Ice.Plugin.IceSSL
differs depending on the language mapping you're using. The Ice.Plugin
properties also support an alternate syntax that allows you to define both variations in the same configuration file if desired.
The IceSSL.DefaultDir
property is a convenient way to specify the default location of your certificate files. The two subsequent properties identify the files containing the trusted CA certificate and the certificate with private key, respectively. When these properties specify a relative path name, as shown here, IceSSL attempts to find these files in the directory defined by IceSSL.DefaultDir
. The file specified in IceSSL.CAs
should normally be in the Privacy Enhanced Mail (PEM) format, whereas the file in IceSSL.CertFile
must use the Personal Information Exchange (PFX, also known as PKCS#12) format and contain both a certificate and its corresponding private key. The IceSSL.Password
property specifies the password used to secure the file.
It is a security risk to define a password in a plain text file, such as an Ice configuration file, because anyone who can gain read access to your configuration file can obtain your password. IceSSL also supports alternate ways to supply a password.
Using Certificate Stores
Windows uses certificate stores as the persistent repositories of certificates and keys. Furthermore, there are two distinct sets of certificate stores, one for the current user and another for the local machine.
Managing Certificates with the Microsoft Management Console
On Windows, you can use the Microsoft Management Console (MMC) to browse the contents of the various certificate stores. To start the console, run MMC.EXE
from a command window, or choose Run from the Start menu and enter MMC.EXE
.
Once the console is running, you need to install the Certificates "snap-in" by choosing Add/Remove Snap-in from the File menu. Click the Add button, choose Certificates in the popup window and click Add. If you wish to manage certificates for the current user, select My Current Account and click Finish. To manage certificates for the local computer, select Computer Account and click Next, then select Local Computer and click Finish.
When you have finished adding snap-ins, close the Add Standalone Snap-in window and click OK on the Add/Remove Snap-in window. Your Console Root window now contains a tree structure that you can expand to view the available certificate stores. If you have a certificate in a file that you want to add to a store, click on the desired store, then open the Action menu and select All Tasks/Import.
Configuring IceSSL using Certificate Stores
If the program's certificate and private key are already installed in a certificate store, you can select it using the IceSSL.FindCert
configuration property as shown in the following example:
Ice.Plugin.IceSSL=... IceSSL.FindCert=subject:"Quote Server" IceSSL.CertStore=My IceSSL.CertStoreLocation=LocalMachine
An IceSSL.FindCert
property executes a query in a particular certificate store and selects all of the certificates that match the given criteria. In the example above, the location of the certificate store is LocalMachine
(as defined by IceSSL.CertStoreLocation
) and the store's name is My
(as defined by IceSSL.CertStore
). When using MMC to browse the certificate stores, this is equivalent to the store "Personal" in the location "Certificates (Local Computer)."
The other legal value for IceSSL.CertStoreLocation
is CurrentUser
. The following table shows the valid values for IceSSL.CertStore
and their equivalents in MMC:
Property Value | MMC Name |
---|---|
| Other People |
| Third-Party Root Certification Authorities |
| Intermediate Certification Authorities |
| Untrusted Certificates |
| Personal |
| Trusted Root Certification Authorities |
| Trusted People |
| Trusted Publishers |
The search criteria consists of name:value pairs that perform case-insensitive comparisons against the fields of each certificate in the specified store, and the special property value *
selects every certificate in the store. Typically, however, the criteria should select a single certificate. In a server, IceSSL must supply Windows with the certificate that represents the server's identity; if a configuration matches several certificates, IceSSL chooses one (in an undefined manner) and logs a warning to notify you of the situation.
Selecting a certificate from a store is more secure than using a certificate file via the IceSSL.CertFile
property because it is not necessary to specify a plain-text password. MMC prompts you for the password when initially importing a certificate into a store, so the password is not required when an application uses that certificate to identify itself.
Trusted CA Certificates
We made no mention of trusted CA certificates in the configuration above. For a program to be able to successfully authenticate a certificate it receives from a peer, all trusted CA certificates must either be loaded via the IceSSL.CAs
property or already be present in the appropriate certificate stores.
When installing a trusted CA certificate, authentication succeeds only when the certificate is installed into one of the following stores:
- Local Computer / Trusted Root Certification Authorities
- Local Computer / Third-Party Root Certification Authorities
- Current User / Trusted Root Certification Authorities
Note that administrative privileges are required when installing a certificate into a Local Computer store.
Configuring IceSSL for C++ on OS X
Our first example shows the properties that are sufficient in many situations:
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.DefaultDir=/opt/certs IceSSL.CertFile=cert.pfx IceSSL.CAs=ca.pem IceSSL.Password=password
The IceSSL.DefaultDir
property is a convenient way to specify the default location of your certificate files. The properties that follow it define the files containing the program's certificate with private key, and trusted CA certificate, respectively. Finally, the IceSSL.Password
property specifies the password necessary to open cert.pfx
.
It is a security risk to define a password in a plain text file, such as an Ice configuration file, because anyone who can gain read access to your configuration file can obtain your password. IceSSL also supports alternate ways to supply a password.
Keychain Examples for OS X
IceSSL imports the certificate specified by IceSSL.CertFile
into a keychain. IceSSL uses the user's default keychain unless you choose a different one by defining the IceSSL.Keychain
property:
IceSSL.Keychain=Test Keychain
If the specified keychain file does not exist, IceSSL will create it. The file name is opened relative to the user's current working directory unless an absolute path name is provided.
The user's default keychain is normally unlocked after logging into the system, so IceSSL doesn't usually require a password to import a certificate into this keychain. However, if your keychain is not unlocked automatically, or if you've selected a different keychain, you can supply a password using the IceSSL.KeychainPassword
property:
IceSSL.KeychainPassword=password
It is a security risk to define a password in a plain text file, such as an Ice configuration file, because anyone who can gain read access to your configuration file can obtain your password.
If you don't define IceSSL.KeychainPassword
and a password is required to open the keychain, OS X will prompt the user for the password.
To use a certificate that's already in a keychain, you can omit the IceSSL.CertFile
and IceSSL.Password
properties and use IceSSL.FindCert
instead:
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.DefaultDir=/opt/certs IceSSL.CAs=ca.pem IceSSL.FindCert=Label:Client
Here we've instructed IceSSL to locate the certificate in the default keychain labeled Client
and use that as the program's identity.
ADH Example for OS X
The following example uses ADH (the Anonymous Diffie-Hellman cipher). ADH is not a good choice in most cases because, as its name implies, there is no authentication of the communicating parties, and it is vulnerable to man-in-the-middle attacks. However, it still provides encryption of the session traffic and requires very little administration and therefore may be useful in certain situations. The configuration properties shown below demonstrate how to use ADH:
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.Ciphers=(DH_anon*) IceSSL.DHParams=dhparams.der IceSSL.VerifyPeer=0
The IceSSL.Ciphers
property enables support for ADH. We also recommend setting IceSSL.DHParams
with the name of a DER-encoded file containing pre-generated DH parameters.
The IceSSL.VerifyPeer
property changes the plug-in's default behavior with respect to certificate verification. Without this setting, IceSSL rejects a connection if the peer does not supply a certificate (as is the case with ADH).
Configuring IceSSL for C++ on Linux
Our first example shows the properties that are sufficient in many situations:
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.DefaultDir=/opt/certs IceSSL.CertFile=cert.pfx IceSSL.CAs=ca.pem IceSSL.Password=password
The IceSSL.DefaultDir
property is a convenient way to specify the default location of your certificate and key files. The two properties that follow it define the files containing the program's certificate with private key and trusted CA certificate, respectively. This example assumes the files contain RSA keys, and IceSSL requires the files to use the Privacy Enhanced Mail (PEM) encoding. Finally, the IceSSL.Password
property specifies the password of the private key.
It is a security risk to define a password in a plain text file, such as an Ice configuration file, because anyone who can gain read access to your configuration file can obtain your password. IceSSL also supports alternate ways to supply a password.
DSA Example for C++
If you used DSA to generate your keys, one additional property is necessary:
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.DefaultDir=/opt/certs IceSSL.CertFile=cert_dsa.pfx IceSSL.CAs=ca.pem IceSSL.Password=password IceSSL.Ciphers=DEFAULT:DSS
The IceSSL.Ciphers
property adds support for DSS authentication to the plug-in's default set of ciphersuites.
RSA and DSA Example for C++
It is also possible to specify certificates and keys for both RSA and DSA by including two filenames in the IceSSL.CertFile
property. The file names must be separated using the platform's path separator. The example below demonstrates the configuration:
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.DefaultDir=/opt/certs IceSSL.CertFile=cert_rsa.pfx:cert_dsa.pfx IceSSL.CAs=ca.pem IceSSL.Password=password IceSSL.Ciphers=DEFAULT:DSS
ADH Example for C++
The following example uses ADH (the Anonymous Diffie-Hellman cipher). ADH is not a good choice in most cases because, as its name implies, there is no authentication of the communicating parties, and it is vulnerable to man-in-the-middle attacks. However, it still provides encryption of the session traffic and requires very little administration and therefore may be useful in certain situations. The configuration properties shown below demonstrate how to use ADH:
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.Ciphers=ADH:!LOW:!MD5:!EXP:!3DES:@STRENGTH IceSSL.VerifyPeer=0
The IceSSL.Ciphers
property enables support for ADH (which is disabled by default) and eliminates low-strength ciphersuites.
The IceSSL.VerifyPeer
property changes the plug-in's default behavior with respect to certificate verification. Without this setting, IceSSL rejects a connection if the peer does not supply a certificate (as is the case with ADH).
Configuring IceSSL for Java
IceSSL uses Java's native format for storing keys and certificates: the keystore.
A keystore is represented as a file containing key pairs and associated certificates, and is usually administered using the keytool
utility supplied with the Java run time. Keystores serve two roles in Java's SSL architecture:
- A keystore containing a key pair identifies the peer and is usually closely guarded.
- A keystore containing public certificates represents the identities of trusted peers and can be freely shared. These keystores are also referred to as "truststores" when they are used to store only trusted certificate chains.
A single keystore file can fulfill both of these purposes.
Java supports a pluggable architecture for keystore implementations in which a system property selects a particular implementation as the default keystore type. IceSSL uses the default keystore type unless otherwise specified.
A password is assigned to each key pair in a keystore, as well as to the keystore itself. IceSSL must be provided with the password for the key pair, but the keystore password is optional. If a keystore password is specified, it is used only to verify the keystore's integrity. IceSSL requires that all of the key pairs in a keystore have the same password.
Our first example shows the properties that are sufficient in many situations:
Ice.Plugin.IceSSL=IceSSL.PluginFactory IceSSL.DefaultDir=/opt/certs IceSSL.Keystore=keys.jks IceSSL.Truststore=ca.jks IceSSL.Password=password
IceSSL resolves the filenames defined in its configuration properties as follows:
- Attempt to open the file as a class loader resource. This is especially useful for deploying applications with special security restrictions, such as applets.
- Attempt to open the file in the local file system.
- If
IceSSL.DefaultDir
is defined, prepend its value and try steps 1 and 2 again. TheIceSSL.DefaultDir
property is a convenient way to specify the default location of your keystore and truststore files.
The IceSSL.Password
property specifies the password of the key pair.
It is a security risk to define a password in a plain text file, such as an Ice configuration file, because anyone who can gain read access to your configuration file can obtain your password. IceSSL also supports alternate ways to supply a password.
DSA Example for Java
Java supports both RSA and DSA keys. No additional properties are necessary to use DSA:
Ice.Plugin.IceSSL=IceSSL.PluginFactory IceSSL.DefaultDir=/opt/certs IceSSL.Keystore=dsakeys.jks IceSSL.Truststore=ca.jks IceSSL.Password=password
ADH Example for Java
The following example uses ADH (the Anonymous Diffie-Hellman cipher). ADH is not a good choice in most cases because, as its name implies, there is no authentication of the communicating parties, and it is vulnerable to man-in-the-middle attacks. However, it still provides encryption of the session traffic and requires very little administration and therefore may be useful in certain situations. The configuration properties shown below demonstrate how to use ADH:
Ice.Plugin.IceSSL=IceSSL.PluginFactory IceSSL.DefaultDir=/opt/certs IceSSL.Ciphers=NONE (DH_anon.*AES) IceSSL.VerifyPeer=0
The IceSSL.Ciphers
property enables support for ADH, which is disabled by default. Furthermore, this setting enables only those ADH ciphersuites that support AES encryption and eliminates other, lower-strength ciphersuites that may not be supported by recent JVMs.
The IceSSL.VerifyPeer
property changes the plug-in's default behavior with respect to certificate verification. Without this setting, IceSSL rejects a connection if the peer does not supply a certificate (as is the case with ADH).
Configuring IceSSL for Ice Touch
In Ice Touch, certificate files are loaded from the application's resource bundle. If the application's target platform is OS X, certificate files can also be loaded directly from the file system. Consider the following properties:
IceSSL.DefaultDir=certs IceSSL.CAs=cacert.der IceSSL.CertFile=cert.pfx IceSSL.Password=password
The IceSSL.DefaultDir
property is a convenient way to specify the location of your certificate files. Defining IceSSL.DefaultDir
means IceSSL searches for certificate files relative to the specified directory. For the properties in the example above, IceSSL composes the pathnames certs/cacert.der
and certs/cert.pfx
. If IceSSL.DefaultDir
is not defined, IceSSL uses the certificate file pathnames exactly as they are supplied.
As mentioned earlier, IceSSL has different semantics for locating certificate files depending on the target platform. For the iPhone and iPhone simulator, IceSSL attempts to open a certificate file in the application's resource bundle as Resources/DefaultDir/file
if IceSSL.DefaultDir
is defined, or as simply Resources/file
otherwise. If the target platform is OS X and the certificate file cannot be found in the resource bundle, IceSSL also attempts to open the file in the file system as DefaultDir/file
if a default directory is specified, or as simply file
otherwise.
IceSSL requires that the CA certificate file specified by IceSSL.CAs
use the DER format. The certificate file in IceSSL.CertFile
must use the Personal Information Exchange (PFX, also known as PKCS#12) format and contain both a certificate and its corresponding private key. The IceSSL.Password
property specifies the password used to secure the certificate file.
Keychains
IceSSL imports the certificate specified by IceSSL.CertFile
into a keychain. IceSSL uses the login
keychain by default unless you choose a different one by defining the IceSSL.Keychain
property:
IceSSL.Keychain=Test Keychain
The login
keychain is the user's default keychain, which is normally unlocked after logging into the system. IceSSL does not usually require a password to import a certificate into the login
keychain. However, if your login
keychain is not unlocked automatically, or if you have selected a different keychain, you can supply a password using the IceSSL.KeychainPassword
property:
IceSSL.KeychainPassword=password
Configuring Ciphersuites
A ciphersuite represents a particular combination of encryption, authentication and hashing algorithms. The IceSSL plug-ins for C++ and Java allow you to configure the ciphersuites that their underlying SSL engines are allowed to negotiate during handshaking with a peer. By default, IceSSL uses the underlying engine's default ciphersuites, but you can define a property to customize the list as we demonstrated above with the ADH examples. Normally the default configuration is chosen to eliminate relatively insecure ciphersuites such as ADH, which is the reason it must be explicitly enabled.
Configuring Ciphersuites in C++
The value of the IceSSL.Ciphers
property is given directly to the platform's native SSL implementation, which determines the allowable ciphersuites.
On Linux, the list of ciphersuites supported by OpenSSL depends on how the OpenSSL distribution was compiled. You can obtain a complete list of the supported ciphersuites using the openssl
command:
$ openssl ciphers
This command will likely generate a long list.
In general, we recommend setting IceSSL.Trace.Security=1
when experimenting with ciphersuite configurations. When executing your program, pay special attention to the log output to verify the ciphersuites that IceSSL has enabled.
Refer to the platform notes in the IceSSL.Ciphers
property description for the details about your platform.
Configuring Ciphersuites in Java
IceSSL for Java interprets the value of IceSSL.Ciphers
as a sequence of expressions that filter the selected ciphersuites using name and pattern matching. If the property is not defined, the Java security provider's default ciphersuites are used. The following table defines the valid expressions that may appear in the property value.
Expression | Description |
---|---|
| Disables all ciphersuites. If specified, it must appear first. |
| Enables all supported ciphersuites. If specified, it must appear first. This expression should be used with caution, as it may enable low-security ciphersuites. |
| Enables the ciphersuite matching the given name. |
| Disables the ciphersuite matching the given name. |
| Enables ciphersuites whose names contain the regular expression |
| Disables ciphersuites whose names contain the regular expression |
To determine the set of enabled ciphersuites, the plug-in begins with a list of ciphersuite names containing the default set as determined by the security provider. The expressions in the property value add and remove ciphersuites from this list and are evaluated in the order of appearance. For example, consider the following property definition:
IceSSL.Ciphers=NONE (RSA.*AES) !(EXPORT)
The expressions in this property have the following effects:
NONE
clears the list of enabled ciphersuites.(RSA.*AES)
is a regular expression that enables ciphersuites whose names contain the string "RSA" followed by "AES", meaning ciphersuites using RSA authentication and AES encryption.!(EXPORT)
is a regular expression that disables any of the selected ciphersuites whose names contain the string "EXPORT", meaning ciphersuites having export-quality strength.
As another example, this property adds anonymous Diffie-Hellman to the default set of ciphersuites and disables export ciphersuites:
IceSSL.Client.Ciphers=(DH_anon) !(EXPORT)
Finally, this example selects only one ciphersuite:
IceSSL.Client.Ciphers=NONE SSL_RSA_WITH_RC4_128_SHA
Configuring Trust Relationships
Declaring that you trust a certificate authority implies that you trust any peer whose certificate was signed directly or indirectly by that certificate authority. It is necessary to use this broad definition of trust in some applications, such as a public Web server. In more controlled environments, it is a good idea to restrict access as much as possible, and IceSSL provides a number of ways for you to do that.
Trusted Peers
After the low-level SSL engine has completed its authentication process, IceSSL can be configured to take additional steps to verify whether a peer should be trusted. The IceSSL.TrustOnly
family of properties defines a collection of acceptance and rejection filters that IceSSL applies to the distinguished name of a peer's certificate in order to determine whether to allow the connection to proceed. IceSSL permits the connection if the peer's distinguished name matches any of the acceptance filters and does not match any of the rejection filters.
A distinguished name uniquely identifies a person or entity and is generally represented in the following textual form:
C=US, ST=Florida, L=Palm Beach Gardens, O="ZeroC, Inc.", OU=Servers, CN=Quote Server
Suppose we are configuring a client to communicate with the server whose distinguished name is shown above. If we know that the client is allowed to communicate only with this server, we can enforce this rule using the following property:
IceSSL.TrustOnly=O="ZeroC, Inc.", OU=Servers, CN=Quote Server
With this property in place, IceSSL allows a connection to proceed only if the distinguished name in the server's certificate matches this filter. The property may contain multiple filters, separated by semicolons, if the client needs to communicate with more than one server. Additional variations of the property are also supported.
If the IceSSL.TrustOnly
properties do not provide the selectivity you require, the next step is to install a custom certificate verifier.
Verification Depth
In order to authenticate a peer, SSL obtains the peer's certificate chain, which includes the peer's certificate as well as that of the root CA. SSL verifies that each certificate in the chain is valid, but there still remains a subtle security risk. Suppose that we have identified a trusted root CA (via its certificate), and a peer has supplied a valid certificate chain signed by our trusted root CA. It is possible for an attacker to obtain a special signing certificate that is signed by our root CA and therefore trusted implicitly. The attacker can use this certificate to sign fraudulent certificates with the goal of masquerading as a trusted peer, presumably for some nefarious purpose.
We could use the IceSSL.TrustOnly
properties described above in an attempt to defend against such an attack. However, the attacker could easily manufacture a certificate containing a distinguished name that satisfies the trust properties.
If you know that all trusted peers present certificate chains of a certain length, set the property IceSSL.VerifyDepthMax
so that IceSSL automatically rejects longer chains. The default value of this property is three, therefore you may need to set it to a larger value if you expect peers to present longer chains.
In situations where you cannot make assumptions about the length of a peer's certificate chain, yet you still want to examine the chain before allowing the connection, you should install a custom certificate verifier.
Configuring Secure Proxies
Proxies may contain any combination of secure and insecure endpoints. An application that requires secure communication can guarantee that proxies it manufactures itself, such as those created by calling stringToProxy
, contain only secure endpoints. However, the application cannot make the same assumption about proxies received as the result of a remote invocation.
The simplest way to guarantee that all proxies use only secure endpoints is to define the Ice.Override.Secure
configuration property:
Ice.Override.Secure=1
Setting this property is equivalent to invoking the proxy method ice_secure(true)
on every proxy. When enabled, attempting to establish a connection using a proxy that does not contain a secure endpoint results in NoEndpointException
.
If you want the default behavior of proxies to give precedence to secure endpoints, you can set this property instead:
Ice.Default.PreferSecure=1
Note that proxies may still attempt to establish connections to insecure endpoints, but they try all secure endpoints first. This is equivalent to invoking ice_preferSecure(true)
on a proxy.
IceSSL Diagnostics
You can use two configuration properties to obtain more information about the plug-in's activities. Setting IceSSL.Trace.Security=1
enables the plug-in's diagnostic output, which includes a variety of messages regarding events such as ciphersuite selection, peer verification and trust evaluation. The other property, Ice.Trace.Network
, determines how much information is logged about network events such as connections and packets. Note that the output generated by Ice.Trace.Network
also includes other transports such as TCP and UDP.
System Logging in Java
In Java, you can use a system property that displays a great deal of information about SSL certificates and connections, including the ciphersuite that is selected for use by each connection. For example, the following command sets the system property that activates the diagnostics:
$ java -Djavax.net.debug=ssl MyProgram
System Logging in .NET
Enabling additional tracing output in .NET requires the creation of an XML file such as the one shown below:
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <system.diagnostics> <trace autoflush="true"/> <sources> <source name="System.Net"> <listeners> <add name="System.Net"/> </listeners> </source> <source name="System.Net.Sockets"> <listeners> <add name="System.Net"/> </listeners> </source> <source name="System.Net.Cache"> <listeners> <add name="System.Net"/> </listeners> </source> </sources> <sharedListeners> <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="trace.txt" /> </sharedListeners> <switches> <add name="System.Net" value="Verbose"/> <add name="System.Net.Sockets" value="Verbose"/> <add name="System.Net.Cache" value="Verbose"/> </switches> </system.diagnostics> </configuration>
In this example, the output is stored in the file trace.txt
. To activate tracing, give the XML file the same name as your executable with a .config
extension (such as server.exe.config
), and place it in the same directory as the executable.
System Logging on OS X
OS X 10.10 (Yosemite) includes a TLS logging facility. To enable it, run the following command in Terminal:
$ sudo defaults write /Library/Preferences/com.apple.security SSLDebugScope -bool true
To see the log entries you must enable logging for warnings in syslog:
$ sudo syslog -c 0 -w
Then run syslog in 'wait' mode:
$ syslog -w