зеркало из https://github.com/mozilla/pjs.git
383 строки
17 KiB
Plaintext
383 строки
17 KiB
Plaintext
<!--
|
|
|
|
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
Portions copyright 1999 Netscape Communications Corporation. All
|
|
Rights Reserved.
|
|
|
|
The contents of this document are subject to the terms of the
|
|
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
|
version (the "License"). You may not use this document except in
|
|
compliance with the License.
|
|
|
|
See the License for the specific language governing
|
|
permissions and limitations under the License. You can obtain
|
|
a copy of the License at
|
|
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
|
|
|
-->
|
|
<chapter id="csdk-ssl"><title>SSL Connections With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>Secure Sockets Layer (SSL)</secondary>
|
|
</indexterm><highlights>
|
|
<para>This chapter describes the process of enabling an LDAP client to connect
|
|
to an LDAP server over the Secure Sockets Layer (SSL) protocol.</para>
|
|
<itemizedlist>
|
|
<para>This chapter covers the following topics:</para>
|
|
<listitem><para><olink targetptr="bdahz">How SSL Works With Directory SDK
|
|
for C</olink></para></listitem>
|
|
<listitem><para><olink targetptr="bdaia">Connecting to a Server Over SSL With
|
|
Directory SDK for C</olink></para></listitem>
|
|
<listitem><para><olink targetptr="bdaic">Handling Errors With Directory SDK
|
|
for C</olink></para></listitem>
|
|
<listitem><para><olink targetptr="ssl-start-tls">Starting Transport Layer
|
|
Security With Directory SDK for C</olink></para></listitem>
|
|
<listitem><para><olink targetptr="bdaid">Installing Your Own SSL I/O Functions
|
|
With Directory SDK for C</olink></para></listitem>
|
|
<listitem><para><olink targetptr="bdaie">Using Certificate-Based Client Authentication
|
|
With Directory SDK for C</olink></para></listitem>
|
|
</itemizedlist>
|
|
</highlights>
|
|
<sect1 id="bdahz"><title>How SSL Works With &DirectorySDKForC;</title>
|
|
<para>The primary goal of the SSL protocol is to provide privacy and reliability
|
|
between two communicating applications.</para>
|
|
<note><para>SSL is not supported on all LDAP servers.</para><para>SSL communication
|
|
must take place on a separate TCP port unless the server supports Start TLS.</para>
|
|
</note>
|
|
<para>When an LDAP client connects to an LDAP server over SSL, the server
|
|
identifies itself by sending a certificate to the client. The client needs
|
|
to determine whether or not the certificate authority (CA) that issued the
|
|
certificate is trusted. The client therefore searches a certificate database
|
|
for the certificate of the CA. If the client cannot find the certificate,
|
|
the client refuses to connect to the server. If the certificate is marked <firstterm>
|
|
not trusted</firstterm>, the client also refuses to connect to the server.</para>
|
|
<para>The LDAP server can also request that the client send a certificate
|
|
to authenticate itself. This part of the process is called <firstterm>certificate-based
|
|
client authentication</firstterm>. If the client receives a request for a
|
|
certificate from the server, the client retrieves its certificate from the
|
|
certificate database. The client sends the certificate to the server for authentication.
|
|
After receiving the client’s certificate, the LDAP server determines
|
|
whether or not the CA that issued the certificate is trusted. If the server
|
|
cannot find the CA certificate in the certificate database, the server refuses
|
|
to authenticate the client. If the CA certificate is marked as <firstterm>not
|
|
trusted</firstterm>, the server also refuses to authenticate the client. If
|
|
the CA is trusted, the server uses the certificate subject name to determine
|
|
whether the client has access to perform the requested operation.</para>
|
|
<itemizedlist>
|
|
<para>&DirectorySDKForC; includes functions that allow you to connect an
|
|
LDAP client to an LDAP server over SSL. The functions make the following assumptions:
|
|
</para>
|
|
<listitem><para>Your client has access to a certificate database. The function
|
|
call uses this certificate database to determine if the client can trust the
|
|
certificate sent from the server.</para><para>Different certificate database
|
|
versions can be incompatible, which might result in database errors.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<itemizedlist>
|
|
<para>The database used contains any one of the following:</para>
|
|
<listitem><para>The certificate of the CA that issued the server’s certificate
|
|
</para></listitem>
|
|
<listitem><para>If the CAs are organized in a hierarchy, the certificate of
|
|
any of the CAs in the hierarchy</para></listitem>
|
|
<listitem><para>The certificate of the LDAP server</para></listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
<listitem><para>The CA certificate is marked as <firstterm>trusted</firstterm> in
|
|
the certificate database.</para></listitem>
|
|
<listitem>
|
|
<itemizedlist>
|
|
<para>If you plan to use certificate-based client authentication, you also
|
|
need the following:</para>
|
|
<listitem><para>A client certificate in the certificate database issued by
|
|
a CA that is trusted by the LDAP server</para></listitem>
|
|
<listitem><para>A public-private key pair in a key file</para></listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<itemizedlist>
|
|
<para>The functions allow you to do the following:</para>
|
|
<listitem><para>Set the session option for communicating with the server over
|
|
SSL.</para><para>See <olink targetptr="bdaia">Connecting to a Server Over
|
|
SSL With Directory SDK for C</olink> for details.</para></listitem>
|
|
<listitem><para>Start transport layer security by using the Start TLS extended
|
|
operation</para><para>See <olink targetptr="ssl-start-tls">Starting Transport
|
|
Layer Security With Directory SDK for C</olink> for details.</para></listitem>
|
|
<listitem><para>Replace the default I/O functions with your own I/O functions
|
|
for communicating over SSL</para><para>See <olink targetptr="bdaid">Installing
|
|
Your Own SSL I/O Functions With Directory SDK for C</olink> for details.</para>
|
|
</listitem>
|
|
<listitem><para>Enable your client to send certificates to authenticate itself</para>
|
|
<para>See <olink targetptr="bdaie">Using Certificate-Based Client Authentication
|
|
With Directory SDK for C</olink> for details.</para></listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
<sect1 id="bdaia"><title>Connecting to a Server Over SSL With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>Secure Sockets Layer (SSL)</secondary>
|
|
<tertiary>connecting to the server</tertiary>
|
|
</indexterm>
|
|
<para>To enable your LDAP client to connect to an LDAP server with SSL, you
|
|
need to perform the following procedure.</para>
|
|
<task><title>To Initialize a Client SSL Connection by Using <function>ldapssl_init
|
|
</function></title>
|
|
<procedure>
|
|
<step><para>Initialize your client by calling one of the following functions:</para>
|
|
<substeps>
|
|
<step><para>Call <function>ldapssl_client_init</function> if you do not plan
|
|
to use certificate-based client authentication.</para></step>
|
|
<step><para>Call <function>ldapssl_clientauth_init</function> if you plan
|
|
to use certificate-based client authentication.</para></step>
|
|
<step><para>Call <function>ldapssl_advclientauth_init</function>.</para><para>If
|
|
you use certificate-based client authentication, you need to specify the path
|
|
of the security module database, or to specify the method to verify the server
|
|
certificate.</para></step></substeps>
|
|
<para>You must initialize your client before initializing the LDAP session.
|
|
The process of initializing the client opens the certificate database.</para>
|
|
</step>
|
|
<step><para>Initialize an LDAP session with the secure server by calling the <function>
|
|
ldapssl_init</function> function.</para><para>For an alternative way to accomplish
|
|
this step, see <olink targetptr="bdaib">Alternative to ldapssl_init</olink>.</para>
|
|
</step>
|
|
</procedure>
|
|
<example id="ssl-init-connection-example">
|
|
<title>To Initialize a Client SSL Connection by using <function>ldapssl_init</function></title>
|
|
<para>This example initializes a client to connect to a secure LDAP server
|
|
over SSL.</para>
|
|
<programlisting>if ( ldapssl_client_init( "/local/examples/alias/", NULL ) < 0) {
|
|
printf( "Failed to initialize SSL client...\n" );
|
|
return( 1 );
|
|
}
|
|
/* get a handle to an LDAP connection */
|
|
if ( (ld = ldapssl_init( "cert.example.com", LDAPS_PORT, 1 )) == NULL {
|
|
perror( "ldapssl_init" );
|
|
return( 1 );
|
|
}
|
|
...
|
|
/* Client can now perform LDAP operations on the secure LDAP server. */
|
|
...</programlisting>
|
|
</example>
|
|
</task>
|
|
<sect2 id="bdaib"><title>Alternative to <function>ldapssl_init</function></title>
|
|
<para>As an alternative to calling the <function>ldapssl_init</function> function,
|
|
you can use the following procedure.</para>
|
|
<task><title>To Initialize a Client SSL Connection (Alternative Method Using <function>
|
|
ldap_init</function></title>
|
|
<procedure>
|
|
<step><para>After initializing your client, initialize an LDAP session with
|
|
the server by calling the standard initialization function <function>ldap_init</function>.
|
|
</para></step>
|
|
<step><para>Install the standard SSL I/O functions by calling <function>ldapssl_install_routines
|
|
</function>.</para></step>
|
|
<step><para>Set the SSL option in the LDAP structure by calling <function>ldap_set_option
|
|
</function>.</para></step>
|
|
</procedure>
|
|
<example id="ssl-init-alt-connection-example">
|
|
<title>Initializing a Client SSL Initialization (Alternative Method Using <function>
|
|
ldap_init</function>)</title>
|
|
<para>This example prepares a client to connect to a secure LDAP server over
|
|
SSL using <function>ldap_init</function>.</para>
|
|
<programlisting>if ( ldapssl_client_init( "/local/examples/alias/", NULL ) < 0) {
|
|
printf( "Failed to initialize SSL client...\n" );
|
|
return( 1 );
|
|
}
|
|
/* Initialize LDAP session. Use prldap_init() for IPv6. */
|
|
if ( (ld = ldap_init( MY_HOST, LDAPS_PORT )) == NULL ) {
|
|
perror( "ldap_init" );
|
|
return( 1 );
|
|
}
|
|
|
|
/* Load SSL routines */
|
|
if ( ldapssl_install_routines( ld ) != 0 ) {
|
|
ldap_perror( ld, "ldapssl_install_routines" );
|
|
return( 1 );
|
|
}
|
|
/* Set up option in LDAP struct for using SSL */
|
|
if ( ldap_set_option( ld, LDAP_OPT_SSL, LDAP_OPT_ON ) != 0 ) {
|
|
ldap_perror( ld, "ldap_set_option" );
|
|
return( 1 );
|
|
}
|
|
/* Client can now perform LDAP operations on the secure LDAP server. */
|
|
...</programlisting>
|
|
</example>
|
|
</task>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="bdaic"><title>Handling Errors With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>Secure Sockets Layer (SSL)</secondary>
|
|
<tertiary>handling errors</tertiary>
|
|
</indexterm>
|
|
<para>After calling any of the SSL initialization functions, you can convert
|
|
SSL-specific error codes to text strings by calling <function>ldapssl_err2string</function>.
|
|
The <function>ldapssl_err2string</function> function provides support for
|
|
special SSL error messages that are not handled by the normal error conversion
|
|
routine <function>ldap_err2string</function>. </para></sect1>
|
|
<sect1 id="ssl-start-tls"><title>Starting Transport Layer Security With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>Secure Sockets Layer (SSL)</secondary>
|
|
<tertiary>start TLS</tertiary>
|
|
</indexterm>
|
|
<para><ulink url="http://www.ietf.org/rfc/rfc4513.txt" type="text_url">RFC
|
|
4513</ulink>, <citetitle>Lightweight Directory Access Protocol (LDAP): Authentication
|
|
Methods and Security Mechanisms</citetitle>, describes the extended operation.
|
|
Start TLS allows you to connect to a nonsecure port, and then request transport
|
|
layer security.</para>
|
|
<task><title>To Use Start TLS</title>
|
|
<procedure>
|
|
<step><para>Initialize your client with <function>ldapssl_client_init</function>.
|
|
</para><para>The process of initializing the client opens the certificate
|
|
database.</para></step>
|
|
<step><para>Get a handle to an LDAP connection.</para></step>
|
|
<step><para>Request Start TLS with <function>ldap_start_tls_s</function>.</para>
|
|
</step>
|
|
<step><para>Authenticate to the directory to perform additional operations.</para>
|
|
</step>
|
|
</procedure>
|
|
<example>
|
|
<title>Using Start TLS</title>
|
|
<para>This example connects and uses Start TLS, then requests the Who am I?
|
|
extended operation. The example relies on a certificate database directory, <filename
|
|
class="directory">/local/examples/alias/</filename>.</para>
|
|
<programlisting>/*
|
|
* Use the Start TLS extended operation.
|
|
*/
|
|
|
|
#include "examples.h"
|
|
#include <ldap_ssl.h>
|
|
|
|
/*
|
|
* Path to certificate database for SSL
|
|
*/
|
|
#define CERT_DB_PATH "/local/examples/alias/"
|
|
|
|
int
|
|
main( int argc, char **argv )
|
|
{
|
|
int version;
|
|
LDAP *ld;
|
|
int rc;
|
|
char *authzid;
|
|
|
|
/* Initialize access to the certificate database. */
|
|
if ( ldapssl_client_init( CERT_DB_PATH, NULL ) != 0 ) {
|
|
fprintf( stderr, "ldapssl_client_init failed\n" );
|
|
fprintf( stderr, "certificate database path: %s\n", CERT_DB_PATH );
|
|
return( 1 );
|
|
}
|
|
|
|
/* Use LDAPv3. */
|
|
version = LDAP_VERSION3;
|
|
if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version )
|
|
!= 0 ) {
|
|
fprintf( stderr,
|
|
"ldap_set_option protocol version to %d failed\n",
|
|
version );
|
|
return( 1 );
|
|
}
|
|
|
|
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
|
if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
|
|
perror( "ldap_init" );
|
|
return( 1 );
|
|
}
|
|
|
|
/* Request Start TLS. */
|
|
if ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
|
|
ldap_perror( ld, "ldap_start_tls_s" );
|
|
return( 1 );
|
|
}
|
|
printf( "Start TLS operation successful.\n" );
|
|
|
|
/* Authenticate to the directory. */
|
|
if ( ldap_simple_bind_s( ld, ENTRYDN, ENTRYPW ) != LDAP_SUCCESS ) {
|
|
ldap_perror( ld, "ldap_simple_bind_s" );
|
|
return( 1 );
|
|
}
|
|
|
|
/* Examine my authorization ID. */
|
|
if ( (rc = ldap_whoami_s( ld, NULL, NULL, &authzid ) )
|
|
!= LDAP_SUCCESS ) {
|
|
fprintf( stderr, "ldap_whoami_s: %s\n", ldap_err2string( rc ) );
|
|
ldap_unbind( ld );
|
|
return( 1 );
|
|
}
|
|
printf( "Authorization ID: %s\n", authzid );
|
|
|
|
ldap_unbind( ld );
|
|
return( 0 );
|
|
}</programlisting>
|
|
<para>See <olink targetptr="extendop-whoami">Performing a Who Am I? Extended
|
|
Operation With Directory SDK for C</olink> for details on using the “Who
|
|
am I?” extended operation.</para></example>
|
|
<taskrelated role="troubleshooting">
|
|
<para>To troubleshoot Start TLS problems, call the <function>PR_GetError</function> function.
|
|
This function gives you access to many Network Security Services (NSS) errors
|
|
further documented in the <ulink
|
|
url="http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslerr.html"
|
|
type="text_url">Mozilla.org SSL Reference</ulink>.</para></taskrelated>
|
|
</task>
|
|
</sect1>
|
|
<sect1 id="bdaid"><title>Installing Your Own SSL I/O Functions With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>Secure Sockets Layer (SSL)</secondary>
|
|
<tertiary>custom I/O functions</tertiary>
|
|
</indexterm>
|
|
<para>The <function>ldapssl_init</function> and <function>ldapssl_install_routines
|
|
</function> functions both set up the session to use the standard SSL I/O
|
|
functions provided with &DirectorySDKForC;. If you want to use your own
|
|
SSL I/O functions, use the <structname>ldap_x_ext_io_fns</structname> structure.</para>
|
|
<task><title>To Install Your Own SSL I/O Functions</title>
|
|
<procedure>
|
|
<step><para>Create an <structname>ldap_x_ext_io_fns</structname> structure,
|
|
and set the fields to point to your I/O functions.</para></step>
|
|
<step><para>Call <function>ldap_set_option</function> to point to that structure.
|
|
</para>
|
|
<programlisting>if (ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, &my_io_struct) != 0 ) {
|
|
ldap_perror( ld, "ldap_set_option" );
|
|
return( 1 );
|
|
}</programlisting>
|
|
</step>
|
|
</procedure>
|
|
</task>
|
|
</sect1>
|
|
<sect1 id="bdaie"><title>Using Certificate-Based Client Authentication With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>Secure Sockets Layer (SSL)</secondary>
|
|
<tertiary>certificate-based authentication</tertiary>
|
|
</indexterm>
|
|
<para>Some LDAP servers can be configured to use certificate-based client
|
|
authentication. The server requests that your client send a certificate to
|
|
identify itself. Use the following procedure to configure your client to use
|
|
certificates for authentication.</para>
|
|
<task><title>To Use Certificate-Based Client Authentication</title>
|
|
<procedure>
|
|
<step><para>Initialize your LDAP client by calling either <function>ldapssl_clientauth_init
|
|
</function> or <function>ldapssl_advclientauth_init</function>, not <function>ldapssl_client_init
|
|
</function>.</para><para>U<?Pub Caret1>se <function>ldapssl_advclientauth_init</function> if
|
|
you want to specify the path of a security module database, or to specify
|
|
the method used to verify the server certificate.</para><para>You can use
|
|
one of these functions to initialize your client even if you do not plan to
|
|
use certificate-based client authentication. The functions are equivalent
|
|
to <function>ldapssl_client_init</function>.</para></step>
|
|
<step><para>Initialize an LDAP session with the secure server by calling <function>
|
|
ldapssl_init</function>.</para></step>
|
|
<step><para>Enable your client to authenticate with the secure server by calling <function>
|
|
ldapssl_enable_clientauth</function>.</para></step>
|
|
<step><para>Perform a Simple Authentication and Security Layer (SASL) bind
|
|
operation by using the mechanism <literal>EXTERNAL</literal>. This mechanism
|
|
indicates to the directory server that certificates should be used to authenticate
|
|
clients.</para><para>With &cnDirectoryServer;, if you perform a SASL bind
|
|
operation, but the server cannot find the corresponding directory entry for
|
|
a client certificate, the server returns an <literal>LDAP_INVALID_CREDENTIALS</literal> result
|
|
code with the error message <literal>Client Certificate Mapping Failed</literal>.
|
|
</para></step>
|
|
</procedure>
|
|
</task>
|
|
</sect1>
|
|
</chapter>
|