Chapter 4. Configuration

Table of Contents

1. Access Control
1.1. Channel verification
1.2. Login
1.3. Session management
1.4. ACLs
2. Token and keyconfiguration
2.1. OpenSSL
2.2. Empty
2.3. LunaCA3
2.4. nCipher
2.5. OpenSC
3. OpenSSL
3.1. Certificate Extensions
3.2. Profiles
4. CSRs
4.1. Additional Attributes
4.2. PKCS#10 Requests
4.3. Basic CSR
4.4. SCEP
5. Subject
5.1. Common stuff
5.2. dc style
6. Subject Alternative Name
7. LDAP
7.1. Configuration of the Directory
7.2. Configuration of the online components
7.3. Writing Certificates to the Directory
7.4. Adding an attribute to the LDAP schema
8. SCEP
8.1. OPENCADIR/etc/servers/scep.conf
8.2. OPENCADIR/etc/config.xml
9. Dataexchange
9.1. Configuration
9.2. Adding a new node
10. Databases
10.1. PostgreSQL
10.2. MySQL
10.3. Oracle
10.4. DBM Files
11. Email
11.1. Sendmail with basic SMTP authentication

1. Access Control

Before we begin with the access control itself some introductorily notes about the module ID. Every module in OpenCA has a module-ID. This ID you can find in the configurationfile of a module. The ID is used to create unique serial numbers for the requests. The moduleshift defines how many bits at the beginning of a serial number (the least significant bits) are reserved for the module's ID. The advantage is that you can issue a request at any module of OpenCA without synchronizing the databases at every time you issue a request because the module's ID is part of every request serial. The parameter in the configurationfiles are ModuleID and ModuleShift. You can configure both parameters via ./configure. The options are --with-module-shift, --with-ra-module-id and --with-pub-module-id. The ID of the CA is at every time zero.

OpenCA includes since version 0.9.2 a very powerful access control. The configuration of this access control is completely XML based. The configuration files are placed in OPENCADIR/etc/access_control.The document root element is openca and the complete configuration is placed in the area of the access_control element.

            <openca>
                <access_control>
                    The complete configuration should be here.
                </access_control>
            </openca>
        

The complete system consists of four parts:

  1. channel verification

  2. login

  3. session management

  4. ACLs

Every step is a completely isolated pass except of the second and the third step which are unified in the second pass.

Figure 4.1. Passes of the accesscontrol

This is an overview about the passes of OpenCA's
                        accesscontrol.

If you are looking for a more detailed description then please read the tech guide.

1.1. Channel verification

The channel configuration checks the parameters of the incoming connection to detect misconfigured apaches and obsolete clients. The values in the configuration are regular expressions except of the type. The type defines the type of the environmentvariables which should be tested. Today we support only mod_ssl.

If you use encrypted connection then you must use ssl as protocol. If you need an unencrypted connection like on the CA for the interfaces ca and ca_node then you must use http as protocol if you use mod_ssl. If you use an Apache without mod_ssl then you must use .* to match all incoming protocols. Please remember to set all the keylengths to 0 because otherwise the access control rejects all incoming connections.

Example 4.1. channel configuration

<channel>
    <type>mod_ssl</type>
    <protocol>ssl</protocol>
    <source>192.168.0.1</source>
    <asymmetric_cipher>.*</asymmetric_cipher>
    <asymmetric_keylength>0</asymmetric_keylength>
    <symmetric_cipher>.*</symmetric_cipher>
    <symmetric_keylength>128</symmetric_keylength>
</channel> 

1.2. Login

We implemented three different ways to login to OpenCA:

  • none

  • passwd

  • x509

1.2.1. none

The first possibility means that there is no login and everybody who pass the channel verification can use the interface. This possibility is nothing else than the deactivation of the access control.

This is not only an option for debugging and testing. You can also use this option if you want to use a RA interface on a server which allows only RA access from the local machine but not over a remote computer.

<login>
    <type>none</type>
</login>
                

1.2.2. passwd

This method can be used to login via login and passphrase. OpenCA supports authentication based on 1.) an internal database, 2.) ldap authentication and 3.) based on calling an external program to perform the actual user authentication.

Figure 4.2. Passphrase based login

This is login screen of OpenCA if login method
                                is passwd.

It is possible to customize the headline (default: "Login to OpenCA") and the prompt for the login id (default: "Login"). This can be done with the following two configuration parameters:

Example 4.2. Login screen configuration

<login>
    <loginheadline>This is my customized login screen</loginheadline>
    <loginprompt>my login prompt</loginprompt>
    ...
<login> 

This feature is especially usefull if used with the LDAP authentication (see below), where you can use any attribute, such as email address as login name.

1.2.2.1. internal database

For the 'internal database' method you can specify one or more users. Every user has a name, a role, an algorithm and a digest. The algorithm specify which kind of digest should be used to hash the passphrase. OpenCA supports three algorithms SHA1, MD5 and crypt.

Example 4.3. Login and Passphrase configuration

<login>
    <type>passwd</type>
    <database>internal</database>
    <passwd>
        <user>
            <name>root</name>
            <algorithm>sha1</algorithm>
            <digest>3Hbp8MAAbo+RngxRXGbbujmC94U</digest>
            <role>CA Operator</role>
        </user>
        <user>...</user>
        ...
    </passwd>
</login> 

Before somebody tries to crack this hash the passphrase is root and this is the default passphrase of OpenCA :)

We prepared a script to generate the digests. The name of the script is openca-digest and it will be installed during make install*. The program is used like "openca-digest (help|sha1|crypt|md5) string".

1.2.2.2. LDAP authentication

If you have an LDAP server with login data about your users it makes sense to use it for user authentication in OpenCA. You have to configure the LDAP data for access, being hostname and port of the LDAP server, its base DN (the name space of the server), a bind dn of an entry for OpenCA to authenticate itself, which has to have appropriate access rights configured in the LDAP server, and the respective password, and whether OpenCa shall use TLS encryption in its communication to the LDAP server and the location of the respective CA certificate. Since the configuration file contains a password, it should only be readable for the OpenCA process.

Example 4.4. LDAP Login configuration: LDAP data

<login>
    <type>passwd</type>
    <database>ldap</database>
    <ldapdata>
         <host>ldap.foo.com</host>
         <port>389</port>
         <base>dc=foo,dc=com</base>
         <binddn>cn=openca,ou=services,dc=foo,dc=com</host>
         <bindpw>secret</bindpw>
         <usetls>yes</usetls>
         <cacertpath>/opt/certs/</cacertpath>
         ...
    </ldapdata>
</login> 

Next you have to configure, which LDAP attribute contains the identifier or login name of the users, which could be the uid or even an email address. Some such attributes may contain additional constant strings prefixed to the actual value (e.g. the attribute proxyAddresses when used for emasil addresses can contain the prefix "SMTP": "SMTP:misterx@foo.bar". If this is so you can specify the prefix, so OpenCA finds the user even if she does not include the prefix in the login name.

Example 4.5. LDAP login configuration: search attribute

<login>
    <type>passwd</type>
    <database>ldap</database>
    <ldapdata>
         ...
         <searchattr>uid</searchattr>
         <searchvalueprefix></searchvalueprefix>
         ...
    </ldapdata>
</login> 

The LDAP authentication module supports two different authentication methods:

  1. bind (the generic simple LDAP authentication mechanism using the password stored in attribute userPassword)

  2. pwattr (using the password stored in a freely configurable attribute, see below)

You can use both methods in parallel, but then the module must know which method to use for which entries. This can be defined by values of a certain attribute, which can be defined in the configuration as ldapauthmethattr.

Then you must define which values of that attribute should lead to which authentication method. A good example would be to take the attribute objectClass as ldapauthmethattr and say if the entry contains the objectclass posixaccount to use the ldap bind method, if it contains objectClass externalUser to use pwattr. such mappings can be done with the constructs <ldapauthmethmapping> (see example below).

If none of the conditions configured here are fulfilled by an entry, a default mechanism has to be used, which has to be configured (see example below).

For the pwattr method you need to specify which attribute contains the passwords to use. The values in that attribute can and should be stored as hash values. If so, the module needs to know which hashing algorithm was used. supported are: sha1, md5, crypt and none (=clear text).

Example 4.6. LDAP login configuration: authentication mechanisms

<login>
    <type>passwd</type>
    <database>ldap</database>
    <ldapdata>
        ...
         <ldapauthmethattr>objectclass</authmethattr>
         <ldapauthmethmapping>
            <ldapauthmethattrvalue>posixaccount</ldapauthmethattrvalue>
            <ldapauthmeth>bind</ldapauthmeth>
	 </ldapauthmethmappingt>
         <ldapauthmethmapping>
            <ldapauthmethattrvalue>externalUser</ldapauthmethattrvalue>
            <ldapauthmeth>pwattr</ldapauthmeth>
	 </ldapauthmethmappingt>
         <ldapdefaultauthmeth>bind</ldapdefaultauthmeth>
         <ldappwattr>mypasswordattribute</ldappwattr>
         <ldappwattrhash>sha1</ldappwattrhash>
    </ldapdata>
</login> 

The LDAP Login module also provides for role mapping, where certain values of a certain attribute map to certain OpenCA roles. First you have to specify which LDAP attribute contains the role mapping information. Then you can easily define the mappings (with constructs similiar to the above authmethmapping). This is configured within the <passwd> element:

Example 4.7. LDAP login configuration: role mapping

<login>
    <type>passwd</type>
    <database>ldap</database>
    <ldapdata>
       ...
    </ldapdata>
    <passwd>
       <roleattribute>memberOf</roleattribute>
       <rolemapping>
           <roleattributevalue>CN=OpenCA_RA,OU=UserGroups,dc=foo,dc=com</roleattributevalue>
           <rol>RA Operator</role>
       </rolemapping>
    </passwd>
</login> 
1.2.2.3. external authentication

External authentication can be used to integrate authentication methods that are not natively supported by OpenCA. Essentially this method is a variant of the username/passwort authentiation.

External authentication requires an external program that receives the login credentials that were passed on the login screen via the environment. The external program then must verify if the username/password combination represents a valid login and return an appropriate exit code (0 for success).

The external program should take care of handling the username/password information properly, i. e. it should NOT write this information to files or pass these values to other programs on the command line. The latter is particularly important, as this might open security problems when processing untrusted user input (i. e. the login name or the password). If you must call external programs with this information, please take extra care to tidy the login information of illegal characters (such as quoting special characters). Specification of username or password as command arguments is not directory supported for exactly this reason. Use shell script wrappers that read environment variables instead.

Configuration is straightforward:

Example 4.8. External program authentication configuration

In this example configuration two environment variables USERNAME and PASSWORD are set for the external program /usr/local/bin/authdummy. The special strings '__USER__' and '__PASSWORD__' are replaced with the actual user login information within environment value definitions. An arbitrary number of environment variables may be defined in the configuration file.
<login>
    <type>passwd</type>
    <database>externalcommand</database>
        <setenv>
            <option>
                <name>USERNAME</name>
                <value>__USER__</value>
            </option>
            <option>
                <name>PASSWORD</name>
                <value>__PASSWD__</value>
            </option>
        </setenv>
        <command>/usr/local/bin/authdummy</command>
</login> 

As an example a very simple external authentication program /usr/local/bin/authdummy could (but should not) look like this:

#!/bin/bash
if [ "$USERNAME" = "openca" -a "$PASSWORD" = "rocks" ] ; then
        exit 0
fi
exit 1
		

Again, ALWAYS be sure to check the user input when processing the login data as arguments to external programs, it is easy to open gaping security holes here!

1.2.3. x509

This is perhaps the most advanced method to login. The user must sign it's assigned session ID and the access control verifies the signature. The login name is the serial of the certificate because it is the only unique item in a certificate. The configuration is really simple. You have to set the position of the CA chain and that's all.

Example 4.9. Authentication with certificates

<login
    <type>x509</type>
    <chain>OPENCADIR/var/crypto/chain</chain>
</login> 

The filtering of the users is not the job of the login because the login has only to identify the user. The filtering has to be implemented in the ACLs. Therefore we cannot recommend the x509 (smartcard) authentication until now.

1.3. Session management

The session management is today really simple to configure because we only support one method to manage a session and the only real variable is the lifetime of a cookie after the last action. The lifetime must be value which will be accepted by CGI::Session. The directory contains the management informations for the cookies (like the name of the user).

Example 4.10. Session configuration

<session>
    <type>cookie</type>
    <directory>@var_prefix@/session/cookie</directory>
    <lifetime>1000</lifetime>
<session> 

1.4. ACLs

The basic configuration of OpenCA's access control list is placed in OPENCADIR/etc/access_control/*.xml. The relevant datastructure is like follows:

Example 4.11. Basic ACL configuration

<acl_config>
    <acl>yes</acl>
    <list>@etc_prefix@/rbac/acl.xml</list>
    <command_dir>@etc_prefix@/rbac/cmds</command_dir>
    <module_id>0</module_id>
    <ca_cert>@var_prefix@/crypto/cacerts/cacert.pem</ca_cert>
    <map_role>no</map_role>
    <map_operation>no</map_operation>
</acl_config> 

Following you can find the meanings of the elements:

acl

enable (yes) or disable (no) the access control list - please notice that a deactivated ACL means that every user has full access to ALL OpenCA functions

list

defines the place of the ACL

command_dir

specify the directory which contains the configuration files of the scripts

module_id

This is the id of the interface. This id is unique for every interface.

ca_cert

The CA certificate in PEM format is used to verify signatures. You can use here another certificate than of the CA which you control with this access control. This is useful if you have a user CA and a server CA. You can login into the interface of the server CA with a certificate from the user CA.

map_role

enable (yes) or disable (no) the mapping from certificates to roles if the certificate of the user is known. If the role is defined during passphrase based login then this option causes the use of the specified role and not the login name.

map_operation

enable (yes) or disable (no) the mapping from the names of the scripts to the supplied operation

You should check the access control list itself very carefully after you initialized the basic configuration of the interface. The real access control list is embedded into the access control area and has the following format:

Example 4.12. Permission for serverInfo

<acl>
    <permission>
        <module>0<</module>
        <role>root<</root>
        <operation>serverInfo</operation>
        <owner></owner>
    </permission>
    <permission>...</permission>
    ...
</acl> 

The meanings of the elements are the following ones:

permission

every access right is defined in a permission element

module

this is the module id of the used web interface. Every installed gateway of OpenCA is a module in the terms of RBAC. If you install the RA then there is a new module with the id 1.

role

is the name of the user if map_role is no and the role of the certificate if map_role is yes. The roles are part of every role based system. OpenCA defines a set of default roles which you can simply extend by other roles which you need.

Every certificate will be assigned a role if it is issued on the CA. The role of a certificate service request is the role which the requests asks for. The role of a certificate revocation request is the role of the certificate to which the CRR belongs. The CA-certificate(s) and the CRLs have no explicit role because they have automatically the “superrole”. If there is an action where the user is not identified by a certificate then the role which is used is automatically the empty role. This is sometimes necessary for example if you want to control your public gateway by RBAC.

operation

is the name of the script if map_operation is no and the operation of the script if map_role is yes.

owner

is the role of the object which will be automatically detected by the configuration of the script

All options can be used with regular expressions but of course the parameters are case sensitive. An ACL which allows anything and only requires a valid login looks like this:

Example 4.13. Allow all

<acl>
    <permission>
        <module>.*</module>
        <role>.*</role>
        <operation>.*</operation>
        <owner>.*</owner>
    </permission>
</acl> 

Every command or script has it's own configuration file which contains the name of the command (this is actually a protection against the renaming of files), the name of the operation for which it is used, the way how to find the affected object and the name of the variable which contains the data which is necessary to determine the object by the specified way. Today there are six OWNER_METHODs:

CERTIFICATE_SERIAL

This method is used if an operation affects a certificate and the role should be detected by the serial of the certificate.

REQUEST_SERIAL

This method is used if an operation affects a CSR and the role should be detected by the serial of the CSR.

CRR_SERIAL

This method is used if an operation affects a CRR and the role should be detected by the serial of the CRR. The CRR will be loaded and the certificate which should be revoked will be loaded and the role of the certificate is used.

CGI

The use of this method is not recommended because the role is not protected by any cryptographic mechanisms.

ANY

The operator must have the right to perform this operation for every role.

<empty>

This method is used to signal that an object is handled which affects the CA directly (e.g. CA-certificate, CRL). The operator needs access to the “superrole”.