After installing IceSSL as described in Section 41.3.1, an application typically needs to define a handful of additional properties to configure settings such as the location of certificate and key files. This section provides an introduction to configuring the plug‑in for each of the supported language mappings. For a complete listing of the IceSSL configuration properties, see
Appendix D.
41.4.1 C++
The IceSSL.DefaultDir property is a convenient way to specify the default location of your certificate and key files. The three properties that follow it define the files containing the program’s certificate, 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.
Note that 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. See
Section 41.6.1 for alternate ways to supply IceSSL with a password.
Ice.Plugin.IceSSL=IceSSL:createIceSSL
IceSSL.DefaultDir=/opt/certs
IceSSL.CertFile=pubkey_dsa.pem
IceSSL.KeyFile=privkey_dsa.pem
IceSSL.CertAuthFile=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. See
Appendix D for more information on this property.
It is also possible to specify certificates and keys for both RSA and DSA by including two filenames in the
IceSSL.CertFile and
IceSSL.KeyFile properties. The filenames must be separated using the platform’s path separator. The example below demonstrates the Unix separator (a colon):
Ice.Plugin.IceSSL=IceSSL:createIceSSL
IceSSL.DefaultDir=/opt/certs
IceSSL.CertFile=pubkey_rsa.pem:pubkey_dsa.pem
IceSSL.KeyFile=privkey_rsa.pem:privkey_dsa.pem
IceSSL.CertAuthFile=ca.pem
IceSSL.Password=password
IceSSL.Ciphers=DEFAULT:DSS
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:
The IceSSL.Ciphers property enables support for ADH, which is disabled by default.
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).
See Appendix D for more information on these properties.
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:
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.
3.
If IceSSL.DefaultDir is defined, prepend its value and try steps 1 and 2 again. The
IceSSL.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. Note that 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.
Section 41.6.1 describes a more secure way to configure the plug‑in.
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:
The IceSSL.Ciphers property enables support for ADH, which is disabled by default.
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).
See Appendix D for more information on these properties.
The Common Language Runtime (CLR) in .NET uses certificate stores as the persistent repositories of certificates and keys. Furthermore, the CLR maintains two distinct sets of certificate stores, one for the current user and another for the local machine. Although it is possible to load a certificate and its corresponding private key from a regular file, the CLR requires trusted CA certificates to reside in an appropriate certificate store.
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.
The IceSSL.DefaultDir property is a convenient way to specify the default location of your certificate file. This file 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.
Note that 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. More secure methods of configuring the plug‑in are described in the next section and in
Section 41.6.1.
This configuration assumes that any trusted CA certificates necessary to authenticate the program’s peers are already installed in an appropriate certificate store. You may also use a configuration property to automatically import a certificate from a file, as described in a subsequent section below.
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:
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, and the store’s name is
My. When using MMC to browse the certificate stores, this specification is equivalent to the store “Personal” in the location “Certificates (Local Computer).”
The other legal value for the location component of the property name is CurrentUser.
Table 41.1 shows the valid values for the store name component and their equivalents in MMC.
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 the CLR 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.
IceSSL can be configured to import a certificate into a particular store. The Ice demos and test suites use this capability to ensure that the CA certificate is present, which avoids the need for a user to manually import the certificate using MMC before she could use the Ice sample programs and tests.
The IceSSL.ImportCert property uses the same format for its name as the
IceSSL.FindCert property described above, in that the certificate store’s location and name are part of the property name:
The property’s value is the name of a certificate file and an optional password. If a file is protected with a password, append the password to the property value using a semicolon as the separator. IceSSL uses the value of
IceSSL.DefaultDir to complete the file name if necessary. The CLR accepts a number of encoding formats for the certificate, including PEM, DER and PFX.
The store name should be chosen with care. When installing a trusted CA certificate, authentication succeeds only when the certificate is installed into one of the following stores:
If you specify a store name other than those listed in Table 41.1, IceSSL creates a new store with the given name and adds the certificate to it. Once installed in the specified store, the application (or the user) is responsible for removing the certificate when it is no longer necessary.
In Ice Touch, certificate files are loaded from the application’s resource bundle. If the application’s target platform is Mac OS, certificate files can also be loaded directly from the file system. Consider the following properties:
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 Mac OS 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.CertAuthFile 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.
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:
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:
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 earlier in this section 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.
The value of the IceSSL.Ciphers property is given directly to the low-level OpenSSL library, on which IceSSL is based. Therefore, OpenSSL determines the allowable ciphersuites, which in turn depend on how the OpenSSL distribution was compiled. You can obtain a complete list of the supported ciphersuites using the
openssl command:
Classes and ciphers can be excluded by prefixing them with an exclamation point. The special keyword
@STRENGTH sorts the cipher list in order of their strength, so that SSL gives preference to the more secure ciphers when negotiating a cipher suite. The
@STRENGTH keyword must be the last element in the list.
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.
Table 41.3 defines the valid expressions that may appear in the property value.
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:
•
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 described in Section 41.2.2, 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.
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 (see
Appendix D) 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.
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:
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, as described in
Appendix D.
If the IceSSL.TrustOnly properties do not provide the selectivity you require, the next step is to install a custom certificate verifier (see
Section 41.5).
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 two, 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 (see
Section 41.5).
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.
Setting this property is equivalent to invoking 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.
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.
Refer to Section 32.11.2 for more information on these proxy methods, and
Section 32.11.4 for details on the connection establishment process used by the Ice run time.
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.
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
<?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 as in
server.exe.config, and place it in the same directory as the executable.