Secure Endpoints Inc. 255 W 94th Street PHB, New York NY 10025 USA; phone: +12127699018; AIM: SecureEndpoints


KCA Service for Active Directory

Installation

The Windows KCA service can be downloaded (ZIP). [Refreshed 20080508]

Changes in the 20080508 build:

  1. Added include_cn_uid option.  Defaults to off.
  2. Added cn_uid_prefix option.  Default to the empty string.

Changes in the 20080507 build:

  1. Strip phone extensions from the Display Name for FermiLabs.

Changes in the 20080417 build:

  1. Added fnal_strip_badge_no option.  Defaults to off.
  2. Changed the reporting of the certificate serial number to hex.

Changes in the 20080416 build:

  1. Added krb5_require_hwauth option.  Defaults to off.
  2. Added include_netscape_userid_extension option.  Defaults to on.
  3. Added include_pseudonym option.  Defaults to off.
  4. Added pseudonym_prefix option.  Default to the empty string.

Changes in the 20080402 build:

  1. Added a log message indicating the serial number of the certificate and whether or not the certificate for that serial number was in fact issued.

Changes in the 20080327 build:

  1. Add new kx509 kca.cnf parameter "fail_on_lookup_error".  Set to "yes" in order prevent the issuance of certificates when the TranslateName() call fails.

Changes in the 20080318 build:

  1. Return an error to the client if the generated certificate is too large to fit in the kx509 v2 protocol response which is capped at 1250 bytes.  The previous behavior of the server was to send no response at all.  The client would then timeout and retry the request which would elicit a "krb5 authentication error due to the request replay".
  2. If the socket cannot be bound to the listener port previous builds would successfully start and then proceed to infinitely loop logging errors and filling the disk.
  3. Add "krb5_authorized_realm_<n>" and "krb5_translate_realm_<n>" entries to the [kx509] section of the configuration file.  These entries serve two purposes.  First, the KCA service will now only issue certificates to clients in realms that are explicitly specified in the configuration file with a "krb5_authorized_realm_<n>" entry.  Second, an explicit per realm configuration option is available to specify which realm the account object lookup should take place in.   This is necessary if a foreign principal is being authenticated by Active Directory and the foreign principal has not been bound to an Active Directory account object via setting the User Principal Name field.  If the AD domain is WIN.EXAMPLE.COM and account objects are synchronized with an MIT realm EXAMPLE.COM, then WIN.EXAMPLE.COM can be specified as the "krb5_translate_realm_<n>" for EXAMPLE.COM.

The service consists of kca_service.exe and a pthreads dll. Place them into your desired directory, for example C:\KCA.  The service requires that Kerberos for Windows be installed.

Copy into the same directory the following files:

Once these files are in place, execute "kca_service -i" to register "kcaservice" as an auto-start service. "kca_service -u" will deregister it.

You can test the service without registering it by executing it from the command line.

The following registry values are supported:

HKLM\SYSTEM\CurrentControlSet\Services\KcaService\Parameters\
    "Threaded"  REG_DWORD   [can be 0 or 1]
    "ConfigFile" REG_SZ          [path to the kca.cnf file]

These values will be created automatically when installed. When the values are not present the process runs in a single thread mode and looks for "kca.cnf" in the same directory as kca_service.exe.

This service can be installed on any machine in the domain. It does not require that it be run on a domain controller. It does not use LDAP to query the domain controller.

Each instance of the service should have a separate "user" account defined in the domain. Once the account is created, the following ktpass command can be used as a template for configuring it and generating the keytab file. I used an account named "kca_service" in the WINDOWS.SECURE-ENDPOINTS.COM domain and installed the service on a machine named galatea.windows.secure-endpoints.com.

[D:\]ktpass /out kca_service.keytab /mapuser kca_service@WINDOWS.SECURE-ENDPOINTS.COM 
/pass <Password>
/princ kca_service/galatea.windows.secure-endpoints.com@WINDOWS.SECURE-ENDPOINTS.COM
/DesOnly /mapOp add /crypto DES-CBC-CRC /ptype KRB5_NT_SRV_HST

The output should look something like this:

Targeting domain controller: dc.windows.secure-endpoints.com
Successfully mapped kca_service/galatea.windows.secure-endpoints.com to kca_service.
Key created.
Output keytab to kca_service.keytab:
Keytab version: 0x502
keysize 104 kca_service/galatea.windows.secure-endpoints.com@WINDOWS.SECURE-ENDPOINTS.COM ptype 3 (KRB5_NT_SRV_HST) vno 3 etype 0x1 (DES-CBC-CRC)
keylength 8 (0x525db5b3c707b51a)
Account kca_service has been set for DES-only encryption. 

The "user" account in Active Directory should have the NO_AUTH_REQUIRED flag set in the UserAccountControl property.

Other notes. 

As with the existing KCA service on UNIX, DNS SRV records can be added to the domain to publish their locations to clients.  The service is multi-threaded requires about 6MB of RAM, and is very low impact.  CPU utilization on a Pentium III domain controller rarely exceeds single digit percentages while processing certificate requests.  Unlike the UNIX KCA service, this version does not have the added complexity of LDAP queries.  All requests to obtain the Display Name from the Kerberos Principal are performed with the TranslateName API.  This avoids all of the overhead associated with managing a separate pool of threads for LDAP queries and the additional layer of complexity associated with performing SASL-GSS-Kerberosv5 authentication from within the OpenLDAP library.  With the Windows KCA, the Kerberos v5 keytab is only used to authenticate the incoming client requests.  There is no need to periodically renew service tickets in the background.

The service has undergone stress testing.  With five worker threads the service was able to issue ~100,000 certificates to 40 clients in six hours on a dual processor Pentium III Windows Server 2003 system.

The standard KCA port is 9878/UDP.  The Windows Firewall must be configured to provide access to this port.

The [kx509] section of the OpenSSL configuration file

There are several options that can be set in the [kx509] section to control the behavior of the kca service.

keytab = <file>. The default is to use "kca_service.keytab" located in the same directory as the service executable.

krb5_use_rcache = "yes"|"no".  The default is "yes".  Setting to no disables the use of the Kerberos v5 replay cache.  The replay cache is created in the %TEMP% or %TMP% directory.

min_threads = <number>.   The default is 5.  This value determines the initial number of worker threads created when the service starts.

max_threads = <number>.  The default is 20.  This value determines the maximum number of worker threads that can be created as needed in order to serve incoming requests.

soft_timeout = <seconds>.  The default is 1.  This value determines how long the service will block processing incoming requests when all worker threads are busy processing certificate requests.

cancel_timeout = <seconds>.  The default is .  This value determines how long the service will wait before determining that worker threads have died and should be reborn.

hard_timeout = <seconds>.  The default is 24.  This value determines how long the service will wait before sending a busy error to the caller.

server_port = <number>.  The default is 9878.  This value determines which UDP port number the service listens for requests on.  This value should not be set without understanding the consequences.

krb5_authorized_realm_<n> = Defines a client realm that the KCA service is permitted to issue certificates to.  <n> is a sequential number starting with 1.   For example, "krb5_authorized_realm_1 = EXAMPLE.COM" and "krb5_authorized_realm_2 = WIN.EXAMPLE.COM".

krb5_translate_realm_<n> = Specifies the realm which when combined with the first component of the authenticated client principal can be used to find a matching user object in the Active Directory database.  Typically this will be the Active Directory domain.  The value of <n> used must match the value from krb5_authorized_realm_<n>.   For example, "krb5_translate_realm_1 = WIN.EXAMPLE.COM".

fail_on_lookup_error = "yes"|"no".  The default is "no".  Setting to yes prevents the issuance of certificates when the Win32 TranslateName() API fails.

krb5_require_hwauth = "yes"|"no".  The defaults is "no".  Setting to yes requires that the initial Kerberos ticket granting ticket be obtained using hardware preauthentication.

include_netscape_userid_extension = "yes"|"no".  The default is "yes".  Setting to yes instructs the KCA to include the Netscape UserID Extension component as part of the Subject Distinguished Name.  The included value is the first component of the Kerberos principal name and is only included if the Kerberos principal exists within the Active Directory database.

include_pseudonym = "yes"|"no".  The default is "no".  Setting to yes instructs the KCA to include the Pseudonym component as part of the Subject Distinguished Name.  The included value is the first component of the Kerberos principal name prefixed by the string specified by pseudonym_prefix.  It is only included if the Kerberos principal exists within the Active Directory database.

pseudonym_prefix = "<string>". The default is the empty string.  This string is combined used as a prefix for the generation of the Pseudonym component of the Subject Distinguished Name.

include_cn_uid = "yes"|"no".  The default is "no".  Setting to yes instructs the KCA to include a CN component set to the UserID as part of the Subject Distinguished Name.  The included value is the first component of the Kerberos principal name prefixed by the string specified by cn_uid_prefix.  It is only included if the Kerberos principal exists within the Active Directory database.

cn_uid_prefix = "<string>". The default is the empty string.  This string is combined used as a prefix for the generation of the CN UserID component of the Subject Distinguished Name.

fnal_strip_badge_no = "yes"|"no".  The default is "no".  This option is specific to FermiLab which includes the badge number in the display name of the Active Directory account object but does not wish the badge number to be included in the certificate Subject Distinguished Name.

Changes from the UNIX KCA:

  1. Several memory leaks from the original UMich code base were identified and closed.  Testing shows that there appear to be no additional memory leaks.
  2. Kerberos replay cache management was added.  Previously, the generation of the replay cache name was left up to the MIT Kerberos library.  Unfortunately, the library does not safely manage the generation of the replay cache file in a multi-threaded process.  As a result, each request ends up creating its own replay cache file.  This has the side effect of filling up disk space quite quickly and failing to actually check for replay attacks.  Now the replay cache is created once by the service and safely used by all threads.  The replay cache can also be turned off in order to improve throughput.
  3. A deadlock condition could occur when the UNIX KCA determined that it needed to increase the number of worker threads.  This would only occur when there was a very large number of requests being received.  Restarting the service while the number of incoming requests continued to be high could immediately result in a repeat deadlock.
  4. The worker thread scheduling algorithm was revised.  The KCA is much more aggressive about creating additional worker threads.  If a request arrives and there are no worker threads available, a new worker thread is created (up to the max_threads limit.)  The previous behavior required that a 20 second timeout occur before the new worker thread would be created.  This had two negative side effects:
  5. The display name for the account is acquired by using the Win32 TranslateName API to convert the incoming Kerberos principal name.  No LDAP calls are utilized.  Instead Windows internally performs an RPC to the account management service.
  6. Logging was quite verbose and nightly log rollover was not performed.  All of the debugging messages are now disabled by default.  Logs are created with the date as part of the name.  New log files are automatically created at midnight.  The only entries you should see are: request received, cert sent, request denied due to retry, or incorrect format error.  After the timestamp, the number in the brackets is now the thread id.  This permits each of the requests and responses to be linked together when debugging issues.  Nightly log rollover is managed within the service.

What has not been done:

Issuing Certificates to non-Domain Kerberos principals:

The Windows KCA will only issue certificates to Kerberos principals that are mapped to accounts in Active Directory.   When cross-realm associations are in place, a mapping for user@SECURE-ENDPOINTS.COM can be associated with the "user" account in the WINDOWS.SECURE-ENDPOINTS.COM domain.  This permits certificates to be issued to either user@SECURE-ENDPOINTS.COM or user@WINDOWS.SECURE-ENDPOINTS.COM.

Using KCA Certs with IIS:

IIS permits client certificates to be mapped to domain accounts.  In order to map KCA certificates to domain accounts, use the e-mail field as the mapping key and map the Kerberos principal name that is stored there to the domain account UPN.

KCA Provider for NIM:

For best results, use version 2.1.0.