1 /* tls_m.c - Handle tls/ssl using Mozilla NSS. */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2008-2009 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
16 /* ACKNOWLEDGEMENTS: Initial version written by Howard Chu.
17 * Additional support by Rich Megginson.
24 #include "ldap_config.h"
28 #if defined( HAVE_FCNTL_H )
32 #include <ac/stdlib.h>
34 #include <ac/socket.h>
35 #include <ac/string.h>
38 #include <ac/unistd.h>
40 #include <ac/dirent.h>
46 #include <ldap_pvt_thread.h>
49 #define READ_PASSWORD_FROM_STDIN
50 #define READ_PASSWORD_FROM_FILE
52 #ifdef READ_PASSWORD_FROM_STDIN
53 #include <termios.h> /* for echo on/off */
57 #include <private/pprio.h>
65 typedef struct tlsm_ctx {
68 PRBool tc_verify_cert;
69 CERTCertDBHandle *tc_certdb;
72 struct ldaptls *tc_config;
75 PRCallOnceType tc_callonce;
77 ldap_pvt_thread_mutex_t tc_refmutex;
81 typedef PRFileDesc tlsm_session;
83 static PRDescIdentity tlsm_layer_id;
85 static const PRIOMethods tlsm_PR_methods;
87 static int tlsm_did_init;
89 #define DEFAULT_TOKEN_NAME "default"
91 /* forward declaration */
92 static int tlsm_init( void );
101 #endif /* LDAP_R_COMPILE */
104 tlsm_dump_cipher_info(PRFileDesc *fd)
108 for (ii = 0; ii < SSL_NumImplementedCiphers; ++ii) {
109 PRInt32 cipher = (PRInt32)SSL_ImplementedCiphers[ii];
110 PRBool enabled = PR_FALSE;
112 SSLCipherSuiteInfo info;
115 SSL_CipherPrefGet(fd, cipher, &enabled);
117 SSL_CipherPrefGetDefault(cipher, &enabled);
119 SSL_CipherPolicyGet(cipher, &policy);
120 SSL_GetCipherSuiteInfo(cipher, &info, (PRUintn)sizeof(info));
121 Debug( LDAP_DEBUG_TRACE,
122 "TLS: cipher: %d - %s, enabled: %d, ",
123 info.cipherSuite, info.cipherSuiteName, enabled );
124 Debug( LDAP_DEBUG_TRACE,
125 "policy: %d\n", policy, 0, 0 );
131 /* Cipher definitions */
133 char *ossl_name; /* The OpenSSL cipher name */
134 int num; /* The cipher id */
135 int attr; /* cipher attributes: algorithms, etc */
136 int version; /* protocol version valid for this cipher */
137 int bits; /* bits of strength */
138 int alg_bits; /* bits of the algorithm */
139 int strength; /* LOW, MEDIUM, HIGH */
140 int enabled; /* Enabled by default? */
145 /* cipher attributes */
146 #define SSL_kRSA 0x00000001L
147 #define SSL_aRSA 0x00000002L
148 #define SSL_aDSS 0x00000004L
149 #define SSL_DSS SSL_aDSS
150 #define SSL_eNULL 0x00000008L
151 #define SSL_DES 0x00000010L
152 #define SSL_3DES 0x00000020L
153 #define SSL_RC4 0x00000040L
154 #define SSL_RC2 0x00000080L
155 #define SSL_AES 0x00000100L
156 #define SSL_MD5 0x00000200L
157 #define SSL_SHA1 0x00000400L
158 #define SSL_SHA SSL_SHA1
159 #define SSL_RSA (SSL_kRSA|SSL_aRSA)
161 /* cipher strength */
162 #define SSL_NULL 0x00000001L
163 #define SSL_EXPORT40 0x00000002L
164 #define SSL_EXPORT56 0x00000004L
165 #define SSL_LOW 0x00000008L
166 #define SSL_MEDIUM 0x00000010L
167 #define SSL_HIGH 0x00000020L
169 #define SSL2 0x00000001L
170 #define SSL3 0x00000002L
171 /* OpenSSL treats SSL3 and TLSv1 the same */
174 /* Cipher translation */
176 static cipher_properties ciphers_def[ciphernum] = {
178 {"DES-CBC3-MD5", SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_MD5, SSL2, 168, 168, SSL_HIGH, SSL_ALLOWED},
179 {"RC2-CBC-MD5", SSL_EN_RC2_128_CBC_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5, SSL2, 128, 128, SSL_MEDIUM, SSL_ALLOWED},
180 {"RC4-MD5", SSL_EN_RC4_128_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL2, 128, 128, SSL_MEDIUM, SSL_ALLOWED},
181 {"DES-CBC-MD5", SSL_EN_DES_64_CBC_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_MD5, SSL2, 56, 56, SSL_LOW, SSL_ALLOWED},
182 {"EXP-RC2-CBC-MD5", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5, SSL2, 40, 128, SSL_EXPORT40, SSL_ALLOWED},
183 {"EXP-RC4-MD5", SSL_EN_RC4_128_EXPORT40_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL2, 40, 128, SSL_EXPORT40, SSL_ALLOWED},
186 {"RC4-MD5", SSL_RSA_WITH_RC4_128_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL3, 128, 128, SSL_MEDIUM, SSL_ALLOWED},
187 {"RC4-SHA", SSL_RSA_WITH_RC4_128_SHA, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA1, SSL3, 128, 128, SSL_MEDIUM, SSL_NOT_ALLOWED},
188 {"DES-CBC3-SHA", SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_SHA1, SSL3, 168, 168, SSL_HIGH, SSL_ALLOWED},
189 {"DES-CBC-SHA", SSL_RSA_WITH_DES_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA1, SSL3, 56, 56, SSL_LOW, SSL_ALLOWED},
190 {"EXP-RC4-MD5", SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL3, 40, 128, SSL_EXPORT40, SSL_ALLOWED},
191 {"EXP-RC2-CBC-MD5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5, SSL3, 0, 0, SSL_EXPORT40, SSL_ALLOWED},
192 {"NULL-MD5", SSL_RSA_WITH_NULL_MD5, SSL_kRSA|SSL_aRSA|SSL_eNULL|SSL_MD5, SSL3, 0, 0, SSL_NULL, SSL_NOT_ALLOWED},
193 {"NULL-SHA", SSL_RSA_WITH_NULL_SHA, SSL_kRSA|SSL_aRSA|SSL_eNULL|SSL_SHA1, SSL3, 0, 0, SSL_NULL, SSL_NOT_ALLOWED},
196 {"EXP1024-DES-CBC-SHA", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA, TLS1, 56, 56, SSL_EXPORT56, SSL_ALLOWED},
197 {"EXP1024-RC4-SHA", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA, TLS1, 56, 56, SSL_EXPORT56, SSL_ALLOWED},
198 {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA, TLS1, 128, 128, SSL_HIGH, SSL_NOT_ALLOWED},
199 {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA, TLS1, 256, 256, SSL_HIGH, SSL_NOT_ALLOWED},
202 /* given err which is the current errno, calls PR_SetError with
203 the corresponding NSPR error code */
205 tlsm_map_error(int err)
211 prError = PR_NO_ACCESS_RIGHTS_ERROR;
214 prError = PR_ADDRESS_IN_USE_ERROR;
217 prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
220 prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
223 prError = PR_WOULD_BLOCK_ERROR;
226 * On QNX and Neutrino, EALREADY is defined as EBUSY.
228 #if EALREADY != EBUSY
230 prError = PR_ALREADY_INITIATED_ERROR;
234 prError = PR_BAD_DESCRIPTOR_ERROR;
238 prError = PR_IO_ERROR;
242 prError = PR_FILESYSTEM_MOUNTED_ERROR;
245 prError = PR_CONNECT_ABORTED_ERROR;
248 prError = PR_CONNECT_REFUSED_ERROR;
251 prError = PR_CONNECT_RESET_ERROR;
254 prError = PR_DEADLOCK_ERROR;
258 prError = PR_DIRECTORY_CORRUPTED_ERROR;
263 prError = PR_NO_DEVICE_SPACE_ERROR;
267 prError = PR_FILE_EXISTS_ERROR;
270 prError = PR_ACCESS_FAULT_ERROR;
273 prError = PR_FILE_TOO_BIG_ERROR;
276 prError = PR_HOST_UNREACHABLE_ERROR;
279 prError = PR_IN_PROGRESS_ERROR;
282 prError = PR_PENDING_INTERRUPT_ERROR;
285 prError = PR_INVALID_ARGUMENT_ERROR;
288 prError = PR_IO_ERROR;
291 prError = PR_IS_CONNECTED_ERROR;
294 prError = PR_IS_DIRECTORY_ERROR;
297 prError = PR_LOOP_ERROR;
300 prError = PR_PROC_DESC_TABLE_FULL_ERROR;
303 prError = PR_MAX_DIRECTORY_ENTRIES_ERROR;
306 prError = PR_INVALID_ARGUMENT_ERROR;
310 prError = PR_REMOTE_FILE_ERROR;
314 prError = PR_NAME_TOO_LONG_ERROR;
317 prError = PR_NETWORK_UNREACHABLE_ERROR;
320 prError = PR_SYS_DESC_TABLE_FULL_ERROR;
323 * On SCO OpenServer 5, ENOBUFS is defined as ENOSR.
325 #if defined(ENOBUFS) && (ENOBUFS != ENOSR)
327 prError = PR_INSUFFICIENT_RESOURCES_ERROR;
331 prError = PR_FILE_NOT_FOUND_ERROR;
334 prError = PR_FILE_NOT_FOUND_ERROR;
337 prError = PR_FILE_IS_LOCKED_ERROR;
341 prError = PR_REMOTE_FILE_ERROR;
345 prError = PR_OUT_OF_MEMORY_ERROR;
348 prError = PR_INVALID_ARGUMENT_ERROR;
351 prError = PR_NO_DEVICE_SPACE_ERROR;
355 prError = PR_INSUFFICIENT_RESOURCES_ERROR;
359 prError = PR_NOT_CONNECTED_ERROR;
362 prError = PR_NOT_DIRECTORY_ERROR;
365 prError = PR_NOT_SOCKET_ERROR;
368 prError = PR_FILE_NOT_FOUND_ERROR;
371 prError = PR_NOT_TCP_SOCKET_ERROR;
375 prError = PR_BUFFER_OVERFLOW_ERROR;
379 prError = PR_NO_ACCESS_RIGHTS_ERROR;
382 prError = PR_CONNECT_RESET_ERROR;
386 prError = PR_IO_ERROR;
389 case EPROTONOSUPPORT:
390 prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR;
393 prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
396 prError = PR_INVALID_METHOD_ERROR;
399 prError = PR_READ_ONLY_FILESYSTEM_ERROR;
402 prError = PR_INVALID_METHOD_ERROR;
405 prError = PR_IO_TIMEOUT_ERROR;
407 #if EWOULDBLOCK != EAGAIN
409 prError = PR_WOULD_BLOCK_ERROR;
413 prError = PR_NOT_SAME_DEVICE_ERROR;
416 prError = PR_UNKNOWN_ERROR;
419 PR_SetError( prError, err );
423 * cipher_list is an integer array with the following values:
424 * -1: never enable this cipher
429 nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
438 /* All disabled to start */
439 for (i=0; i<ciphernum; i++)
442 ciphertip = strdup(cipherstr);
443 cipher = ciphers = ciphertip;
445 while (ciphers && (strlen(ciphers))) {
446 while ((*cipher) && (isspace(*cipher)))
451 case '+': /* Add something */
455 case '-': /* Subtract something */
459 case '!': /* Disable something */
468 if ((ciphers = strchr(cipher, ':'))) {
472 /* Do the easy one first */
473 if (!strcmp(cipher, "ALL")) {
474 for (i=0; i<ciphernum; i++) {
475 if (!(ciphers_def[i].attr & SSL_eNULL))
476 cipher_list[i] = action;
478 } else if (!strcmp(cipher, "COMPLEMENTOFALL")) {
479 for (i=0; i<ciphernum; i++) {
480 if ((ciphers_def[i].attr & SSL_eNULL))
481 cipher_list[i] = action;
483 } else if (!strcmp(cipher, "DEFAULT")) {
484 for (i=0; i<ciphernum; i++) {
485 cipher_list[i] = ciphers_def[i].enabled == SSL_ALLOWED ? 1 : 0;
494 while (c && (strlen(c))) {
496 if ((c = strchr(cipher, '+'))) {
500 if (!strcmp(cipher, "RSA")) {
502 } else if ((!strcmp(cipher, "NULL")) || (!strcmp(cipher, "eNULL"))) {
504 } else if (!strcmp(cipher, "AES")) {
506 } else if (!strcmp(cipher, "3DES")) {
508 } else if (!strcmp(cipher, "DES")) {
510 } else if (!strcmp(cipher, "RC4")) {
512 } else if (!strcmp(cipher, "RC2")) {
514 } else if (!strcmp(cipher, "MD5")) {
516 } else if ((!strcmp(cipher, "SHA")) || (!strcmp(cipher, "SHA1"))) {
518 } else if (!strcmp(cipher, "SSLv2")) {
520 } else if (!strcmp(cipher, "SSLv3")) {
522 } else if (!strcmp(cipher, "TLSv1")) {
524 } else if (!strcmp(cipher, "HIGH")) {
525 strength |= SSL_HIGH;
526 } else if (!strcmp(cipher, "MEDIUM")) {
527 strength |= SSL_MEDIUM;
528 } else if (!strcmp(cipher, "LOW")) {
530 } else if ((!strcmp(cipher, "EXPORT")) || (!strcmp(cipher, "EXP"))) {
531 strength |= SSL_EXPORT40|SSL_EXPORT56;
532 } else if (!strcmp(cipher, "EXPORT40")) {
533 strength |= SSL_EXPORT40;
534 } else if (!strcmp(cipher, "EXPORT56")) {
535 strength |= SSL_EXPORT56;
543 /* If we have a mask, apply it. If not then perhaps they provided
544 * a specific cipher to enable.
546 if (mask || strength || protocol) {
547 for (i=0; i<ciphernum; i++) {
548 if (((ciphers_def[i].attr & mask) ||
549 (ciphers_def[i].strength & strength) ||
550 (ciphers_def[i].version & protocol)) &&
551 (cipher_list[i] != -1)) {
552 /* Enable the NULL ciphers only if explicity
554 if (ciphers_def[i].attr & SSL_eNULL) {
555 if (mask & SSL_eNULL)
556 cipher_list[i] = action;
558 cipher_list[i] = action;
562 for (i=0; i<ciphernum; i++) {
563 if (!strcmp(ciphers_def[i].ossl_name, cipher) &&
564 cipher_list[1] != -1)
565 cipher_list[i] = action;
574 /* See if any ciphers were enabled */
576 for (i=0; i<ciphernum; i++) {
577 if (cipher_list[i] == 1)
587 tlsm_parse_ciphers(tlsm_ctx *ctx, const char *str)
589 int cipher_state[ciphernum];
595 rv = nss_parse_ciphers(str, cipher_state);
598 /* First disable everything */
599 for (i = 0; i < SSL_NumImplementedCiphers; i++)
600 SSL_CipherPrefSet(ctx->tc_model, SSL_ImplementedCiphers[i], SSL_NOT_ALLOWED);
602 /* Now enable what was requested */
603 for (i=0; i<ciphernum; i++) {
604 SSLCipherSuiteInfo suite;
607 if (SSL_GetCipherSuiteInfo(ciphers_def[i].num, &suite, sizeof suite)
609 enabled = cipher_state[i] < 0 ? 0 : cipher_state[i];
610 if (enabled == SSL_ALLOWED) {
611 if (PK11_IsFIPS() && !suite.isFIPS)
612 enabled = SSL_NOT_ALLOWED;
614 SSL_CipherPrefSet(ctx->tc_model, ciphers_def[i].num, enabled);
619 return rv == 1 ? 0 : -1;
623 tlsm_bad_cert_handler(void *arg, PRFileDesc *ssl)
625 SECStatus success = SECSuccess;
627 tlsm_ctx *ctx = (tlsm_ctx *)arg;
633 err = PORT_GetError();
636 case SEC_ERROR_UNTRUSTED_ISSUER:
637 case SEC_ERROR_UNKNOWN_ISSUER:
638 case SEC_ERROR_EXPIRED_CERTIFICATE:
639 if (ctx->tc_verify_cert) {
640 success = SECFailure;
644 success = SECFailure;
652 tlsm_dump_security_status(PRFileDesc *fd)
654 char * cp; /* bulk cipher name */
655 char * ip; /* cert issuer DN */
656 char * sp; /* cert subject DN */
657 int op; /* High, Low, Off */
658 int kp0; /* total key bits */
659 int kp1; /* secret key bits */
660 SSL3Statistics * ssl3stats = SSL_GetStatistics();
662 SSL_SecurityStatus( fd, &op, &cp, &kp0, &kp1, &ip, &sp );
663 Debug( LDAP_DEBUG_TRACE,
664 "TLS certificate verification: subject: %s, issuer: %s, cipher: %s, ",
665 sp ? sp : "-unknown-", ip ? ip : "-unknown-", cp ? cp : "-unknown-" );
669 Debug( LDAP_DEBUG_TRACE,
670 "security level: %s, secret key bits: %d, total key bits: %d, ",
671 ((op == SSL_SECURITY_STATUS_ON_HIGH) ? "high" :
672 ((op == SSL_SECURITY_STATUS_ON_LOW) ? "low" : "off")),
675 Debug( LDAP_DEBUG_TRACE,
676 "cache hits: %ld, cache misses: %ld, cache not reusable: %ld\n",
677 ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses,
678 ssl3stats->hch_sid_cache_not_ok );
684 tlsm_auth_cert_handler(void *arg, PRFileDesc *fd,
685 PRBool checksig, PRBool isServer)
687 SECStatus ret = SSL_AuthCertificate(arg, fd, checksig, isServer);
689 Debug( LDAP_DEBUG_TRACE,
690 "TLS certificate verification: %s: %s,",
691 ret == SECSuccess ? "ok" : "bad",
692 tlsm_dump_security_status( fd ), 0 );
694 if ( ret != SECSuccess ) {
695 PRErrorCode errcode = PORT_GetError();
696 Debug( LDAP_DEBUG_ANY,
697 "TLS certificate verification: Error, %d: %s\n",
698 errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), 0 ) ;
705 tlsm_dirname(const char *pathname)
709 char sep = PR_GetDirectorySeparator();
711 if (pathname && (p = PL_strrchr(pathname, sep)) && (p > pathname)) {
712 ret = PL_strndup(pathname, (p - pathname));
719 * This is the part of the init we defer until we get the
720 * actual security configuration information. This is
721 * only called once, protected by a PRCallOnce
722 * NOTE: This must be done before the first call to SSL_ImportFD,
723 * especially the setting of the policy
724 * NOTE: This must be called after fork()
727 tlsm_deferred_init( void *arg )
729 tlsm_ctx *ctx = (tlsm_ctx *)arg;
730 struct ldaptls *lt = ctx->tc_config;
731 char *securitydir = NULL;
736 /* NSS support for multi-init is coming */
737 #ifndef NSS_MULTI_INIT
738 if ( !NSS_IsInitialized() ) {
739 #endif /* NSS_MULTI_INIT */
741 MOZNSS_DIR will override everything else - you can
742 always set MOZNSS_DIR to force the use of this
744 DEFAULT_MOZNSS_DIR will only be used if the code cannot
745 find a security dir to use based on the current
748 if ( (val = PR_GetEnv( "MOZNSS_DIR" ) ) && (*val) ) {
749 securitydir = PL_strdup( val );
751 } else if ( lt->lt_cacertdir ) {
752 securitydir = lt->lt_cacertdir;
753 } else if ( lt->lt_cacertfile ) {
754 securitydir = tlsm_dirname( lt->lt_cacertfile );
756 } else if ( lt->lt_certfile ) {
757 securitydir = tlsm_dirname( lt->lt_certfile );
759 } else if ( lt->lt_keyfile ) {
760 securitydir = tlsm_dirname( lt->lt_keyfile );
762 } else if ( (val = PR_GetEnv( "DEFAULT_MOZNSS_DIR" ) ) && (*val) ) {
763 securitydir = PL_strdup( val );
766 securitydir = "/etc/pki/nssdb";
769 if ( NSS_Initialize( securitydir, "", "", SECMOD_DB, NSS_INIT_READONLY ) ) {
770 errcode = PORT_GetError();
771 Debug( LDAP_DEBUG_ANY,
772 "TLS: could not initialize moznss using security dir %s - error %d:%s.\n",
773 securitydir, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
775 PL_strfree( securitydir );
781 PL_strfree( securitydir );
784 NSS_SetDomesticPolicy();
785 tlsm_did_init = 1; /* we did the init - we should also clean up */
786 #ifndef NSS_MULTI_INIT
788 #endif /* NSS_MULTI_INIT */
793 #ifdef READ_PASSWORD_FROM_FILE
795 tlsm_get_pin_from_file(const char *token_name, tlsm_ctx *ctx)
798 char *contents = NULL;
801 char *candidate = NULL;
802 PRFileInfo file_info;
803 PRFileDesc *pwd_fileptr = PR_Open( ctx->tc_pin_file, PR_RDONLY, 00400 );
805 /* open the password file */
806 if ( !pwd_fileptr ) {
807 PRErrorCode errcode = PR_GetError();
808 Debug( LDAP_DEBUG_ANY,
809 "TLS: could not open security pin file %s - error %d:%s.\n",
810 ctx->tc_pin_file, errcode,
811 PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
815 /* get the file size */
816 if ( PR_SUCCESS != PR_GetFileInfo( ctx->tc_pin_file, &file_info ) ) {
817 PRErrorCode errcode = PR_GetError();
818 Debug( LDAP_DEBUG_ANY,
819 "TLS: could not get file info from pin file %s - error %d:%s.\n",
820 ctx->tc_pin_file, errcode,
821 PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
825 /* create a buffer to hold the file contents */
826 if ( !( contents = PR_MALLOC( file_info.size + 1 ) ) ) {
827 PRErrorCode errcode = PR_GetError();
828 Debug( LDAP_DEBUG_ANY,
829 "TLS: could not alloc a buffer for contents of pin file %s - error %d:%s.\n",
830 ctx->tc_pin_file, errcode,
831 PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
835 /* read file into the buffer */
836 if( PR_Read( pwd_fileptr, contents, file_info.size ) <= 0 ) {
837 PRErrorCode errcode = PR_GetError();
838 Debug( LDAP_DEBUG_ANY,
839 "TLS: could not read the file contents from pin file %s - error %d:%s.\n",
840 ctx->tc_pin_file, errcode,
841 PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
845 /* format is [tokenname:]password EOL [tokenname:]password EOL ... */
846 /* if you want to use a password containing a colon character, use
847 the special tokenname "default" */
848 for ( line = PL_strtok_r( contents, "\r\n", &lasts ); line;
849 line = PL_strtok_r( NULL, "\r\n", &lasts ) ) {
853 continue; /* skip blank lines */
855 colon = PL_strchr( line, ':' );
857 if ( *(colon + 1) && token_name &&
858 !PL_strncmp( token_name, line, colon-line ) ) {
859 candidate = colon + 1; /* found a definite match */
861 } else if ( !PL_strncmp( DEFAULT_TOKEN_NAME, line, colon-line ) ) {
862 candidate = colon + 1; /* found possible match */
864 } else { /* no token name */
870 PR_Close( pwd_fileptr );
873 pwdstr = PL_strdup( candidate );
875 PL_strfree( contents );
879 #endif /* READ_PASSWORD_FROM_FILE */
881 #ifdef READ_PASSWORD_FROM_STDIN
883 * Turn the echoing off on a tty.
888 if ( isatty( fd ) ) {
890 tcgetattr( fd, &tio );
891 tio.c_lflag &= ~ECHO;
892 tcsetattr( fd, TCSAFLUSH, &tio );
897 * Turn the echoing on on a tty.
902 if ( isatty( fd ) ) {
904 tcgetattr( fd, &tio );
906 tcsetattr( fd, TCSAFLUSH, &tio );
907 tcsetattr( fd, TCSAFLUSH, &tio );
910 #endif /* READ_PASSWORD_FROM_STDIN */
913 * This does the actual work of reading the pin/password/pass phrase
916 tlsm_get_pin(PK11SlotInfo *slot, PRBool retry, tlsm_ctx *ctx)
918 char *token_name = NULL;
921 token_name = PK11_GetTokenName( slot );
922 #ifdef READ_PASSWORD_FROM_FILE
923 /* Try to get the passwords from the password file if it exists.
924 * THIS IS UNSAFE and is provided for convenience only. Without this
925 * capability the server would have to be started in foreground mode
926 * if using an encrypted key.
928 if ( ctx->tc_pin_file ) {
929 pwdstr = tlsm_get_pin_from_file( token_name, ctx );
931 #endif /* RETRIEVE_PASSWORD_FROM_FILE */
932 #ifdef READ_PASSWORD_FROM_STDIN
934 int infd = PR_FileDesc2NativeHandle( PR_STDIN );
935 int isTTY = isatty( infd );
936 unsigned char phrase[200];
937 /* Prompt for password */
940 "Please enter pin, password, or pass phrase for security token '%s': ",
941 token_name ? token_name : DEFAULT_TOKEN_NAME );
944 fgets( (char*)phrase, sizeof(phrase), stdin );
946 fprintf( stdout, "\n" );
949 /* stomp on newline */
950 phrase[strlen((char*)phrase)-1] = 0;
952 pwdstr = PL_strdup( (char*)phrase );
955 #endif /* READ_PASSWORD_FROM_STDIN */
960 * PKCS11 devices (including the internal softokn cert/key database)
961 * may be protected by a pin or password or even pass phrase
962 * MozNSS needs a way for the user to provide that
965 tlsm_pin_prompt(PK11SlotInfo *slot, PRBool retry, void *arg)
967 tlsm_ctx *ctx = (tlsm_ctx *)arg;
969 return tlsm_get_pin( slot, retry, ctx );
973 tlsm_authenticate( tlsm_ctx *ctx, const char *certname, const char *pininfo )
975 const char *colon = NULL;
976 char *token_name = NULL;
977 PK11SlotInfo *slot = NULL;
980 if ( !certname || !*certname ) {
984 PK11_SetPasswordFunc( tlsm_pin_prompt );
986 if ( ( colon = PL_strchr( certname, ':' ) ) ) {
987 token_name = PL_strndup( certname, colon-certname );
991 slot = PK11_FindSlotByName( token_name );
993 slot = PK11_GetInternalKeySlot();
997 PRErrorCode errcode = PR_GetError();
998 Debug( LDAP_DEBUG_ANY,
999 "TLS: could not find the slot for security token %s - error %d:%s.\n",
1000 token_name ? token_name : DEFAULT_TOKEN_NAME, errcode,
1001 PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
1006 PL_strfree( ctx->tc_pin_file );
1007 ctx->tc_pin_file = PL_strdup( pininfo );
1010 if ( PK11_NeedLogin( slot ) &&
1011 ( SECSuccess != PK11_Authenticate( slot, PR_FALSE, ctx ) ) ) {
1012 PRErrorCode errcode = PR_GetError();
1013 Debug( LDAP_DEBUG_ANY,
1014 "TLS: could not authenticate to the security token %s - error %d:%s.\n",
1015 token_name ? token_name : DEFAULT_TOKEN_NAME, errcode,
1016 PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
1019 rc = 0; /* success */
1023 PL_strfree( token_name );
1025 PK11_FreeSlot( slot );
1032 * Find and verify the certificate.
1033 * Either fd is given, in which case the cert will be taken from it via SSL_PeerCertificate
1034 * or certname is given, and it will be searched for by name
1037 tlsm_find_and_verify_cert_key(tlsm_ctx *ctx, PRFileDesc *fd, const char *certname, int isServer, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey)
1039 CERTCertificate *cert = NULL;
1041 void *pin_arg = NULL;
1042 SECKEYPrivateKey *key = NULL;
1044 pin_arg = SSL_RevealPinArg( fd );
1046 cert = PK11_FindCertFromNickname( certname, pin_arg );
1048 PRErrorCode errcode = PR_GetError();
1049 Debug( LDAP_DEBUG_ANY,
1050 "TLS: error: the certificate %s could not be found in the database - error %d:%s\n",
1051 certname, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
1055 /* we are verifying the peer cert
1056 we also need to swap the isServer meaning */
1057 cert = SSL_PeerCertificate( fd );
1059 PRErrorCode errcode = PR_GetError();
1060 Debug( LDAP_DEBUG_ANY,
1061 "TLS: error: could not get the certificate from the peer connection - error %d:%s\n",
1062 errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), NULL );
1065 isServer = !isServer; /* verify the peer's cert instead */
1068 key = PK11_FindKeyByAnyCert( cert, pin_arg );
1070 SECCertificateUsage certUsage;
1071 PRBool checkSig = PR_TRUE;
1075 *pRetKey = key; /* caller will deal with this */
1077 SECKEY_DestroyPrivateKey( key );
1080 certUsage = certificateUsageSSLServer;
1082 certUsage = certificateUsageSSLClient;
1084 if ( ctx->tc_verify_cert ) {
1087 checkSig = PR_FALSE;
1089 status = CERT_VerifyCertificateNow( ctx->tc_certdb, cert,
1090 checkSig, certUsage,
1092 if (status != SECSuccess) {
1093 PRErrorCode errcode = PR_GetError();
1094 Debug( LDAP_DEBUG_ANY,
1095 "TLS: error: the certificate %s is not valid - error %d:%s\n",
1096 certname, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
1098 rc = 0; /* success */
1101 PRErrorCode errcode = PR_GetError();
1102 Debug( LDAP_DEBUG_ANY,
1103 "TLS: error: could not find the private key for certificate %s - error %d:%s\n",
1104 certname, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
1108 *pRetCert = cert; /* caller will deal with this */
1110 CERT_DestroyCertificate( cert );
1117 tlsm_get_client_auth_data( void *arg, PRFileDesc *fd,
1118 CERTDistNames *caNames, CERTCertificate **pRetCert,
1119 SECKEYPrivateKey **pRetKey )
1121 tlsm_ctx *ctx = (tlsm_ctx *)arg;
1124 /* don't need caNames - this function will call CERT_VerifyCertificateNow
1125 which will verify the cert against the known CAs */
1126 rc = tlsm_find_and_verify_cert_key( ctx, fd, ctx->tc_certname, 0, pRetCert, pRetKey );
1128 Debug( LDAP_DEBUG_ANY,
1129 "TLS: error: unable to perform client certificate authentication for "
1130 "certificate named %s\n", ctx->tc_certname, 0, 0 );
1138 * ctx must have a tc_model that is valid
1139 * certname is in the form [<tokenname>:]<certnickname>
1140 * where <tokenname> is the name of the PKCS11 token
1141 * and <certnickname> is the nickname of the cert/key in
1145 tlsm_clientauth_init( tlsm_ctx *ctx, const char *certname )
1147 SECStatus status = SECFailure;
1150 PL_strfree( ctx->tc_certname );
1151 rc = tlsm_find_and_verify_cert_key( ctx, ctx->tc_model, certname, 0, NULL, NULL );
1153 Debug( LDAP_DEBUG_ANY,
1154 "TLS: error: unable to set up client certificate authentication for "
1155 "certificate named %s\n", certname, 0, 0 );
1159 ctx->tc_certname = PL_strdup( certname );
1161 status = SSL_GetClientAuthDataHook( ctx->tc_model,
1162 tlsm_get_client_auth_data,
1165 return ( status == SECSuccess ? 0 : -1 );
1169 * Tear down the TLS subsystem. Should only be called once.
1172 tlsm_destroy( void )
1174 /* Only if we did the actual initialization */
1175 if ( tlsm_did_init ) {
1178 SSL_ShutdownServerSessionIDCache();
1179 SSL_ClearSessionCache();
1187 tlsm_ctx_new ( struct ldapoptions *lo )
1191 ctx = LDAP_MALLOC( sizeof (*ctx) );
1194 #ifdef LDAP_R_COMPILE
1195 ldap_pvt_thread_mutex_init( &ctx->tc_refmutex );
1197 ctx->tc_config = &lo->ldo_tls_info; /* pointer into lo structure - must have global scope and must not go away before we can do real init */
1198 ctx->tc_certdb = NULL;
1199 ctx->tc_certname = NULL;
1200 ctx->tc_pin_file = NULL;
1201 ctx->tc_model = NULL;
1202 memset(&ctx->tc_callonce, 0, sizeof(ctx->tc_callonce));
1203 ctx->tc_require_cert = lo->ldo_tls_require_cert;
1208 return (tls_ctx *)ctx;
1212 tlsm_ctx_ref( tls_ctx *ctx )
1214 tlsm_ctx *c = (tlsm_ctx *)ctx;
1215 #ifdef LDAP_R_COMPILE
1216 ldap_pvt_thread_mutex_lock( &c->tc_refmutex );
1219 #ifdef LDAP_R_COMPILE
1220 ldap_pvt_thread_mutex_unlock( &c->tc_refmutex );
1225 tlsm_ctx_free ( tls_ctx *ctx )
1227 tlsm_ctx *c = (tlsm_ctx *)ctx;
1232 #ifdef LDAP_R_COMPILE
1233 ldap_pvt_thread_mutex_lock( &c->tc_refmutex );
1235 refcount = --c->tc_refcnt;
1236 #ifdef LDAP_R_COMPILE
1237 ldap_pvt_thread_mutex_unlock( &c->tc_refmutex );
1241 PR_Close( c->tc_model );
1242 c->tc_certdb = NULL; /* if not the default, may have to clean up */
1243 PL_strfree( c->tc_certname );
1244 c->tc_certname = NULL;
1245 PL_strfree( c->tc_pin_file );
1246 c->tc_pin_file = NULL;
1247 #ifdef LDAP_R_COMPILE
1248 ldap_pvt_thread_mutex_destroy( &c->tc_refmutex );
1254 * initialize a new TLS context
1257 tlsm_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
1259 tlsm_ctx *ctx = (tlsm_ctx *)lo->ldo_tls_ctx;
1260 ctx->tc_is_server = is_server;
1266 tlsm_deferred_ctx_init( void *arg )
1268 tlsm_ctx *ctx = (tlsm_ctx *)arg;
1269 PRBool sslv2 = PR_FALSE;
1270 PRBool sslv3 = PR_TRUE;
1271 PRBool tlsv1 = PR_TRUE;
1272 PRBool request_cert = PR_FALSE;
1273 PRInt32 require_cert = PR_FALSE;
1277 if ( tlsm_deferred_init( ctx ) ) {
1278 Debug( LDAP_DEBUG_ANY,
1279 "TLS: could perform TLS system initialization.\n",
1284 ctx->tc_certdb = CERT_GetDefaultCertDB(); /* replace with multi-init db call */
1286 fd = PR_CreateIOLayerStub( tlsm_layer_id, &tlsm_PR_methods );
1288 ctx->tc_model = SSL_ImportFD( NULL, fd );
1291 if ( !ctx->tc_model ) {
1292 PRErrorCode err = PR_GetError();
1293 Debug( LDAP_DEBUG_ANY,
1294 "TLS: could perform TLS socket I/O layer initialization - error %d:%s.\n",
1295 err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL );
1303 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_SECURITY, PR_TRUE ) ) {
1304 Debug( LDAP_DEBUG_ANY,
1305 "TLS: could not set secure mode on.\n",
1310 lt = ctx->tc_config;
1312 /* default is sslv3 and tlsv1 */
1313 if ( lt->lt_protocol_min ) {
1314 if ( lt->lt_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL3 ) {
1316 } else if ( lt->lt_protocol_min <= LDAP_OPT_X_TLS_PROTOCOL_SSL2 ) {
1318 Debug( LDAP_DEBUG_ANY,
1319 "TLS: warning: minimum TLS protocol level set to "
1320 "include SSLv2 - SSLv2 is insecure - do not use\n", 0, 0, 0 );
1323 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_ENABLE_SSL2, sslv2 ) ) {
1324 Debug( LDAP_DEBUG_ANY,
1325 "TLS: could not set SSLv2 mode on.\n",
1329 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_ENABLE_SSL3, sslv3 ) ) {
1330 Debug( LDAP_DEBUG_ANY,
1331 "TLS: could not set SSLv3 mode on.\n",
1335 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_ENABLE_TLS, tlsv1 ) ) {
1336 Debug( LDAP_DEBUG_ANY,
1337 "TLS: could not set TLSv1 mode on.\n",
1342 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_HANDSHAKE_AS_CLIENT, !ctx->tc_is_server ) ) {
1343 Debug( LDAP_DEBUG_ANY,
1344 "TLS: could not set handshake as client.\n",
1348 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_HANDSHAKE_AS_SERVER, ctx->tc_is_server ) ) {
1349 Debug( LDAP_DEBUG_ANY,
1350 "TLS: could not set handshake as server.\n",
1355 if ( lt->lt_ciphersuite &&
1356 tlsm_parse_ciphers( ctx, lt->lt_ciphersuite )) {
1357 Debug( LDAP_DEBUG_ANY,
1358 "TLS: could not set cipher list %s.\n",
1359 lt->lt_ciphersuite, 0, 0 );
1363 if ( ctx->tc_require_cert ) {
1364 request_cert = PR_TRUE;
1365 require_cert = SSL_REQUIRE_NO_ERROR;
1366 if ( ctx->tc_require_cert == LDAP_OPT_X_TLS_DEMAND ||
1367 ctx->tc_require_cert == LDAP_OPT_X_TLS_HARD ) {
1368 require_cert = SSL_REQUIRE_ALWAYS;
1370 ctx->tc_verify_cert = PR_TRUE;
1372 ctx->tc_verify_cert = PR_FALSE;
1375 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_REQUEST_CERTIFICATE, request_cert ) ) {
1376 Debug( LDAP_DEBUG_ANY,
1377 "TLS: could not set request certificate mode.\n",
1382 if ( SECSuccess != SSL_OptionSet( ctx->tc_model, SSL_REQUIRE_CERTIFICATE, require_cert ) ) {
1383 Debug( LDAP_DEBUG_ANY,
1384 "TLS: could not set require certificate mode.\n",
1389 /* Set up callbacks for use by clients */
1390 if ( !ctx->tc_is_server ) {
1391 if ( SSL_OptionSet( ctx->tc_model, SSL_NO_CACHE, PR_TRUE ) != SECSuccess ) {
1392 PRErrorCode err = PR_GetError();
1393 Debug( LDAP_DEBUG_ANY,
1394 "TLS: error: could not set nocache option for moznss - error %d:%s\n",
1395 err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL );
1399 if ( SSL_BadCertHook( ctx->tc_model, tlsm_bad_cert_handler, ctx ) != SECSuccess ) {
1400 PRErrorCode err = PR_GetError();
1401 Debug( LDAP_DEBUG_ANY,
1402 "TLS: error: could not set bad cert handler for moznss - error %d:%s\n",
1403 err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL );
1407 /* we don't currently support import of cert/key pair - assume the certfile
1408 is really the name of a cert/key in the database in the form of
1409 tokenname:certname - also assume since this is specified, the caller
1410 wants to attempt client cert auth */
1411 if ( lt->lt_certfile ) {
1412 if ( tlsm_authenticate( ctx, lt->lt_certfile, lt->lt_keyfile ) ) {
1413 Debug( LDAP_DEBUG_ANY,
1414 "TLS: error: unable to authenticate to the security device for certificate %s\n",
1415 lt->lt_certfile, 0, 0 );
1418 if ( tlsm_clientauth_init( ctx, lt->lt_certfile ) ) {
1419 Debug( LDAP_DEBUG_ANY,
1420 "TLS: error: unable to set up client certificate authentication using %s\n",
1421 lt->lt_certfile, 0, 0 );
1425 } else { /* set up secure server */
1427 CERTCertificate *serverCert;
1428 SECKEYPrivateKey *serverKey;
1431 /* must have a certificate for the server to use */
1432 if ( !lt->lt_certfile ) {
1433 Debug( LDAP_DEBUG_ANY,
1434 "TLS: error: no server certificate: must specify a certificate for the server to use\n",
1439 /* authenticate to the server's token - this will do nothing
1440 if the key/cert db is not password protected */
1441 if ( tlsm_authenticate( ctx, lt->lt_certfile, lt->lt_keyfile ) ) {
1442 Debug( LDAP_DEBUG_ANY,
1443 "TLS: error: unable to authenticate to the security device for certificate %s\n",
1444 lt->lt_certfile, 0, 0 );
1448 /* get the server's key and cert */
1449 if ( tlsm_find_and_verify_cert_key( ctx, ctx->tc_model, lt->lt_certfile, ctx->tc_is_server,
1450 &serverCert, &serverKey ) ) {
1451 Debug( LDAP_DEBUG_ANY,
1452 "TLS: error: unable to find and verify server's cert and key for certificate %s\n",
1453 lt->lt_certfile, 0, 0 );
1457 certKEA = NSS_FindCertKEAType( serverCert );
1458 /* configure the socket to be a secure server socket */
1459 status = SSL_ConfigSecureServer( ctx->tc_model, serverCert, serverKey, certKEA );
1460 /* SSL_ConfigSecureServer copies these */
1461 CERT_DestroyCertificate( serverCert );
1462 SECKEY_DestroyPrivateKey( serverKey );
1464 if ( SECSuccess != status ) {
1465 PRErrorCode err = PR_GetError();
1466 Debug( LDAP_DEBUG_ANY,
1467 "TLS: error: unable to configure secure server using certificate %s - error %d:%s\n",
1468 lt->lt_certfile, err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) );
1473 /* Callback for authenticating certificate */
1474 if ( SSL_AuthCertificateHook( ctx->tc_model, tlsm_auth_cert_handler,
1475 ctx->tc_certdb ) != SECSuccess ) {
1476 PRErrorCode err = PR_GetError();
1477 Debug( LDAP_DEBUG_ANY,
1478 "TLS: error: could not set auth cert handler for moznss - error %d:%s\n",
1479 err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL );
1487 tlsm_session *session;
1488 Sockbuf_IO_Desc *sbiod;
1489 /* there seems to be no portable way to determine if the
1490 sockbuf sd has been set to nonblocking mode - the
1491 call to ber_pvt_socket_set_nonblock() takes place
1492 before the tls socket is set up, so we cannot
1493 intercept that call either.
1494 On systems where fcntl is available, we can just
1495 F_GETFL and test for O_NONBLOCK. On other systems,
1496 we will just see if the IO op returns EAGAIN or EWOULDBLOCK,
1497 and just set this flag */
1502 tlsm_is_io_ready( PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags )
1505 PRFileDesc *pollfd = NULL;
1507 PRPollDesc polldesc;
1510 myfd = PR_GetIdentitiesLayer( fd, tlsm_layer_id );
1516 p = (struct tls_data *)myfd->secret;
1518 if ( p == NULL || p->sbiod == NULL ) {
1522 /* wrap the sockbuf fd with a NSPR FD created especially
1523 for use with polling, and only with polling */
1524 pollfd = PR_CreateSocketPollFd( p->sbiod->sbiod_sb->sb_fd );
1525 polldesc.fd = pollfd;
1526 polldesc.in_flags = in_flags;
1527 polldesc.out_flags = 0;
1529 /* do the poll - no waiting, no blocking */
1530 rc = PR_Poll( &polldesc, 1, PR_INTERVAL_NO_WAIT );
1532 /* unwrap the socket */
1533 PR_DestroySocketPollFd( pollfd );
1535 /* rc will be either 1 if IO is ready, 0 if IO is not
1536 ready, or -1 if there was some error (and the caller
1537 should use PR_GetError() to figure out what */
1539 *out_flags = polldesc.out_flags;
1544 static tls_session *
1545 tlsm_session_new ( tls_ctx * ctx, int is_server )
1547 tlsm_ctx *c = (tlsm_ctx *)ctx;
1548 tlsm_session *session;
1552 c->tc_is_server = is_server;
1553 status = PR_CallOnceWithArg( &c->tc_callonce, tlsm_deferred_ctx_init, c );
1554 if ( PR_SUCCESS != status ) {
1555 PRErrorCode err = PR_GetError();
1556 Debug( LDAP_DEBUG_ANY,
1557 "TLS: error: could not initialize moznss security context - error %d:%s\n",
1558 err, PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT), NULL );
1562 fd = PR_CreateIOLayerStub( tlsm_layer_id, &tlsm_PR_methods );
1567 session = SSL_ImportFD( c->tc_model, fd );
1574 /* 0 means use the defaults here */
1575 SSL_ConfigServerSessionIDCache( 0, 0, 0, NULL );
1578 return (tls_session *)session;
1582 tlsm_session_accept( tls_session *session )
1584 tlsm_session *s = (tlsm_session *)session;
1587 int waitcounter = 0;
1589 rc = SSL_ResetHandshake( s, PR_TRUE /* server */ );
1591 err = PR_GetError();
1592 Debug( LDAP_DEBUG_TRACE,
1593 "TLS: error: accept - reset handshake failure %d - error %d:%s\n",
1595 err ? PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) : "unknown" );
1604 rc = SSL_ForceHandshake( s );
1605 if (rc == SECSuccess) {
1609 err = PR_GetError();
1610 Debug( LDAP_DEBUG_TRACE,
1611 "TLS: error: accept - force handshake failure %d - error %d waitcounter %d\n",
1612 errno, err, waitcounter );
1613 if ( errno == EAGAIN || errno == EWOULDBLOCK ) {
1615 in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
1618 filesReady = tlsm_is_io_ready( s, in_flags, &out_flags );
1619 if ( filesReady < 0 ) {
1620 err = PR_GetError();
1621 Debug( LDAP_DEBUG_ANY,
1622 "TLS: error: accept - error waiting for socket to be ready: %d - error %d:%s\n",
1624 err ? PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) : "unknown" );
1626 break; /* hard error */
1627 } else if ( out_flags & PR_POLL_NVAL ) {
1628 PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
1629 Debug( LDAP_DEBUG_ANY,
1630 "TLS: error: accept failure - invalid socket\n",
1634 } else if ( out_flags & PR_POLL_EXCEPT ) {
1635 err = PR_GetError();
1636 Debug( LDAP_DEBUG_ANY,
1637 "TLS: error: accept - error waiting for socket to be ready: %d - error %d:%s\n",
1639 err ? PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) : "unknown" );
1641 break; /* hard error */
1643 } else { /* hard error */
1644 err = PR_GetError();
1645 Debug( LDAP_DEBUG_ANY,
1646 "TLS: error: accept - force handshake failure: %d - error %d:%s\n",
1648 err ? PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) : "unknown" );
1650 break; /* hard error */
1652 } while (rc == SECFailure);
1654 Debug( LDAP_DEBUG_TRACE,
1655 "TLS: accept completed after %d waits\n", waitcounter, NULL, NULL );
1661 tlsm_session_connect( LDAP *ld, tls_session *session )
1663 tlsm_session *s = (tlsm_session *)session;
1667 /* By default, NSS checks the cert hostname for us */
1668 rc = SSL_ResetHandshake( s, PR_FALSE /* server */ );
1670 err = PR_GetError();
1671 Debug( LDAP_DEBUG_TRACE,
1672 "TLS: error: connect - reset handshake failure %d - error %d:%s\n",
1674 err ? PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) : "unknown" );
1677 rc = SSL_SetURL( s, ld->ld_options.ldo_defludp->lud_host );
1679 err = PR_GetError();
1680 Debug( LDAP_DEBUG_TRACE,
1681 "TLS: error: connect - seturl failure %d - error %d:%s\n",
1683 err ? PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) : "unknown" );
1686 rc = SSL_ForceHandshake( s );
1688 err = PR_GetError();
1689 Debug( LDAP_DEBUG_TRACE,
1690 "TLS: error: connect - force handshake failure %d - error %d:%s\n",
1692 err ? PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ) : "unknown" );
1699 tlsm_session_upflags( Sockbuf *sb, tls_session *session, int rc )
1701 /* Should never happen */
1704 if ( rc != PR_PENDING_INTERRUPT_ERROR && rc != PR_WOULD_BLOCK_ERROR )
1710 tlsm_session_errmsg( int rc, char *buf, size_t len )
1715 i = PR_GetErrorTextLength();
1717 char *msg = LDAP_MALLOC( i+1 );
1718 PR_GetErrorText( msg );
1719 memcpy( buf, msg, len );
1722 PR_GetErrorText( buf );
1725 return i ? buf : NULL;
1729 tlsm_session_my_dn( tls_session *session, struct berval *der_dn )
1731 tlsm_session *s = (tlsm_session *)session;
1732 CERTCertificate *cert;
1734 cert = SSL_LocalCertificate( s );
1735 if (!cert) return LDAP_INVALID_CREDENTIALS;
1737 der_dn->bv_val = cert->derSubject.data;
1738 der_dn->bv_len = cert->derSubject.len;
1739 CERT_DestroyCertificate( cert );
1744 tlsm_session_peer_dn( tls_session *session, struct berval *der_dn )
1746 tlsm_session *s = (tlsm_session *)session;
1747 CERTCertificate *cert;
1749 cert = SSL_PeerCertificate( s );
1750 if (!cert) return LDAP_INVALID_CREDENTIALS;
1752 der_dn->bv_val = cert->derSubject.data;
1753 der_dn->bv_len = cert->derSubject.len;
1754 CERT_DestroyCertificate( cert );
1759 tlsm_session_chkhost( LDAP *ld, tls_session *session, const char *name_in )
1761 /* NSS already does a hostname check */
1762 return LDAP_SUCCESS;
1766 tlsm_session_strength( tls_session *session )
1768 tlsm_session *s = (tlsm_session *)session;
1771 rc = SSL_SecurityStatus( s, NULL, NULL, NULL, &keySize,
1773 return rc ? 0 : keySize;
1777 * TLS support for LBER Sockbufs
1780 static PRStatus PR_CALLBACK
1781 tlsm_PR_Close(PRFileDesc *fd)
1783 int rc = PR_SUCCESS;
1785 /* we don't need to actually close anything here, just
1786 pop our io layer off the stack */
1787 fd->secret = NULL; /* must have been freed before calling PR_Close */
1789 fd = PR_PopIOLayer( fd, tlsm_layer_id );
1790 /* if we are not the last layer, pass the close along */
1795 rc = fd->methods->close( fd );
1798 /* we are the last layer - just call our dtor */
1805 static PRStatus PR_CALLBACK
1806 tlsm_PR_Shutdown(PRFileDesc *fd, PRShutdownHow how)
1808 int rc = PR_SUCCESS;
1811 rc = PR_Shutdown( fd->lower, how );
1817 static int PR_CALLBACK
1818 tlsm_PR_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
1819 PRIntervalTime timeout)
1824 if ( buf == NULL || len <= 0 ) return 0;
1826 p = (struct tls_data *)fd->secret;
1828 if ( p == NULL || p->sbiod == NULL ) {
1832 rc = LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
1834 tlsm_map_error( errno );
1835 if ( errno == EAGAIN || errno == EWOULDBLOCK ) {
1836 p->nonblock = PR_TRUE; /* fd is using non-blocking io */
1837 } else if ( errno ) { /* real error */
1838 Debug( LDAP_DEBUG_TRACE,
1839 "TLS: error: tlsm_PR_Recv returned %d - error %d:%s\n",
1840 rc, errno, STRERROR(errno) );
1847 static int PR_CALLBACK
1848 tlsm_PR_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
1849 PRIntervalTime timeout)
1854 if ( buf == NULL || len <= 0 ) return 0;
1856 p = (struct tls_data *)fd->secret;
1858 if ( p == NULL || p->sbiod == NULL ) {
1862 rc = LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len );
1864 tlsm_map_error( errno );
1865 if ( errno == EAGAIN || errno == EWOULDBLOCK ) {
1866 p->nonblock = PR_TRUE;
1867 } else if ( errno ) { /* real error */
1868 Debug( LDAP_DEBUG_TRACE,
1869 "TLS: error: tlsm_PR_Send returned %d - error %d:%s\n",
1870 rc, errno, STRERROR(errno) );
1877 static int PR_CALLBACK
1878 tlsm_PR_Read(PRFileDesc *fd, void *buf, PRInt32 len)
1880 return tlsm_PR_Recv( fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT );
1883 static int PR_CALLBACK
1884 tlsm_PR_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
1886 return tlsm_PR_Send( fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT );
1889 static PRStatus PR_CALLBACK
1890 tlsm_PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
1896 p = (struct tls_data *)fd->secret;
1898 if ( p == NULL || p->sbiod == NULL ) {
1901 len = sizeof(PRNetAddr);
1902 return getpeername( p->sbiod->sbiod_sb->sb_fd, (struct sockaddr *)addr, &len );
1905 static PRStatus PR_CALLBACK
1906 tlsm_PR_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
1909 p = (struct tls_data *)fd->secret;
1915 /* only the nonblocking option is supported at this time
1916 MozNSS SSL code needs it */
1917 if ( data->option != PR_SockOpt_Nonblocking ) {
1918 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
1922 int flags = fcntl( p->sbiod->sbiod_sb->sb_fd, F_GETFL );
1923 data->value.non_blocking = (flags & O_NONBLOCK) ? PR_TRUE : PR_FALSE;
1925 data->value.non_blocking = p->nonblock;
1930 static PRStatus PR_CALLBACK
1933 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
1937 static PRFileDesc * PR_CALLBACK
1940 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
1944 static PRInt16 PR_CALLBACK
1947 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
1951 static PRInt32 PR_CALLBACK
1954 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
1958 static PRInt64 PR_CALLBACK
1963 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
1968 static const PRIOMethods tlsm_PR_methods = {
1970 tlsm_PR_Close, /* close */
1971 tlsm_PR_Read, /* read */
1972 tlsm_PR_Write, /* write */
1973 tlsm_PR_i32_unimp, /* available */
1974 tlsm_PR_i64_unimp, /* available64 */
1975 tlsm_PR_prs_unimp, /* fsync */
1976 tlsm_PR_i32_unimp, /* seek */
1977 tlsm_PR_i64_unimp, /* seek64 */
1978 tlsm_PR_prs_unimp, /* fileInfo */
1979 tlsm_PR_prs_unimp, /* fileInfo64 */
1980 tlsm_PR_i32_unimp, /* writev */
1981 tlsm_PR_prs_unimp, /* connect */
1982 tlsm_PR_pfd_unimp, /* accept */
1983 tlsm_PR_prs_unimp, /* bind */
1984 tlsm_PR_prs_unimp, /* listen */
1985 (PRShutdownFN)tlsm_PR_Shutdown, /* shutdown */
1986 tlsm_PR_Recv, /* recv */
1987 tlsm_PR_Send, /* send */
1988 tlsm_PR_i32_unimp, /* recvfrom */
1989 tlsm_PR_i32_unimp, /* sendto */
1990 (PRPollFN)tlsm_PR_i16_unimp, /* poll */
1991 tlsm_PR_i32_unimp, /* acceptread */
1992 tlsm_PR_i32_unimp, /* transmitfile */
1993 tlsm_PR_prs_unimp, /* getsockname */
1994 tlsm_PR_GetPeerName, /* getpeername */
1995 tlsm_PR_i32_unimp, /* getsockopt OBSOLETE */
1996 tlsm_PR_i32_unimp, /* setsockopt OBSOLETE */
1997 tlsm_PR_GetSocketOption, /* getsocketoption */
1998 tlsm_PR_i32_unimp, /* setsocketoption */
1999 tlsm_PR_i32_unimp, /* Send a (partial) file with header/trailer*/
2000 (PRConnectcontinueFN)tlsm_PR_prs_unimp, /* connectcontinue */
2001 tlsm_PR_i32_unimp, /* reserved for future use */
2002 tlsm_PR_i32_unimp, /* reserved for future use */
2003 tlsm_PR_i32_unimp, /* reserved for future use */
2004 tlsm_PR_i32_unimp /* reserved for future use */
2008 * Initialize TLS subsystem. Should be called only once.
2015 tlsm_layer_id = PR_GetUniqueIdentity( "OpenLDAP" );
2017 /* see deferred init */
2022 tlsm_sb_setup( Sockbuf_IO_Desc *sbiod, void *arg )
2025 tlsm_session *session = arg;
2028 assert( sbiod != NULL );
2030 p = LBER_MALLOC( sizeof( *p ) );
2035 fd = PR_GetIdentitiesLayer( session, tlsm_layer_id );
2041 fd->secret = (PRFilePrivate *)p;
2042 p->session = session;
2044 sbiod->sbiod_pvt = p;
2049 tlsm_sb_remove( Sockbuf_IO_Desc *sbiod )
2053 assert( sbiod != NULL );
2054 assert( sbiod->sbiod_pvt != NULL );
2056 p = (struct tls_data *)sbiod->sbiod_pvt;
2057 PR_Close( p->session );
2058 LBER_FREE( sbiod->sbiod_pvt );
2059 sbiod->sbiod_pvt = NULL;
2064 tlsm_sb_close( Sockbuf_IO_Desc *sbiod )
2068 assert( sbiod != NULL );
2069 assert( sbiod->sbiod_pvt != NULL );
2071 p = (struct tls_data *)sbiod->sbiod_pvt;
2072 PR_Shutdown( p->session, PR_SHUTDOWN_BOTH );
2077 tlsm_sb_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
2081 assert( sbiod != NULL );
2082 assert( sbiod->sbiod_pvt != NULL );
2084 p = (struct tls_data *)sbiod->sbiod_pvt;
2086 if ( opt == LBER_SB_OPT_GET_SSL ) {
2087 *((tlsm_session **)arg) = p->session;
2090 } else if ( opt == LBER_SB_OPT_DATA_READY ) {
2091 if ( tlsm_is_io_ready( p->session, PR_POLL_READ, NULL ) > 0 ) {
2097 return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
2101 tlsm_sb_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
2107 assert( sbiod != NULL );
2108 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
2110 p = (struct tls_data *)sbiod->sbiod_pvt;
2112 ret = PR_Recv( p->session, buf, len, 0, PR_INTERVAL_NO_TIMEOUT );
2114 err = PR_GetError();
2115 if ( err == PR_PENDING_INTERRUPT_ERROR || err == PR_WOULD_BLOCK_ERROR ) {
2116 sbiod->sbiod_sb->sb_trans_needs_read = 1;
2117 sock_errset(EWOULDBLOCK);
2120 sbiod->sbiod_sb->sb_trans_needs_read = 0;
2126 tlsm_sb_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
2132 assert( sbiod != NULL );
2133 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
2135 p = (struct tls_data *)sbiod->sbiod_pvt;
2137 ret = PR_Send( p->session, (char *)buf, len, 0, PR_INTERVAL_NO_TIMEOUT );
2139 err = PR_GetError();
2140 if ( err == PR_PENDING_INTERRUPT_ERROR || err == PR_WOULD_BLOCK_ERROR ) {
2141 sbiod->sbiod_sb->sb_trans_needs_write = 1;
2142 sock_errset(EWOULDBLOCK);
2146 sbiod->sbiod_sb->sb_trans_needs_write = 0;
2151 static Sockbuf_IO tlsm_sbio =
2153 tlsm_sb_setup, /* sbi_setup */
2154 tlsm_sb_remove, /* sbi_remove */
2155 tlsm_sb_ctrl, /* sbi_ctrl */
2156 tlsm_sb_read, /* sbi_read */
2157 tlsm_sb_write, /* sbi_write */
2158 tlsm_sb_close /* sbi_close */
2161 tls_impl ldap_int_tls_impl = {
2173 tlsm_session_connect,
2174 tlsm_session_accept,
2175 tlsm_session_upflags,
2176 tlsm_session_errmsg,
2178 tlsm_session_peer_dn,
2179 tlsm_session_chkhost,
2180 tlsm_session_strength,
2184 #ifdef LDAP_R_COMPILE
2193 #endif /* HAVE_MOZNSS */