Home | History | Annotate | Line # | Download | only in libldap
      1 /*	$NetBSD: tls2.c,v 1.5 2025/09/05 21:16:22 christos Exp $	*/
      2 
      3 /* tls.c - Handle tls/ssl. */
      4 /* $OpenLDAP$ */
      5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6  *
      7  * Copyright 1998-2024 The OpenLDAP Foundation.
      8  * All rights reserved.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted only as authorized by the OpenLDAP
     12  * Public License.
     13  *
     14  * A copy of this license is available in the file LICENSE in the
     15  * top-level directory of the distribution or, alternatively, at
     16  * <http://www.OpenLDAP.org/license.html>.
     17  */
     18 /* ACKNOWLEDGEMENTS: restructured by Howard Chu.
     19  */
     20 
     21 #include <sys/cdefs.h>
     22 __RCSID("$NetBSD: tls2.c,v 1.5 2025/09/05 21:16:22 christos Exp $");
     23 
     24 #include "portable.h"
     25 #include "ldap_config.h"
     26 
     27 #include <stdio.h>
     28 
     29 #include <ac/stdlib.h>
     30 #include <ac/errno.h>
     31 #include <ac/socket.h>
     32 #include <ac/string.h>
     33 #include <ac/ctype.h>
     34 #include <ac/time.h>
     35 #include <ac/unistd.h>
     36 #include <ac/param.h>
     37 #include <ac/dirent.h>
     38 
     39 #include "ldap-int.h"
     40 
     41 #ifdef HAVE_TLS
     42 
     43 #include "ldap-tls.h"
     44 
     45 static tls_impl *tls_imp = &ldap_int_tls_impl;
     46 #define HAS_TLS( sb )	ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
     47 				(void *)tls_imp->ti_sbio )
     48 
     49 #endif /* HAVE_TLS */
     50 
     51 /* RFC2459 minimum required set of supported attribute types
     52  * in a certificate DN
     53  */
     54 typedef struct oid_name {
     55 	struct berval oid;
     56 	struct berval name;
     57 } oid_name;
     58 
     59 static oid_name oids[] = {
     60 	{ BER_BVC("2.5.4.3"), BER_BVC("cn") },
     61 	{ BER_BVC("2.5.4.4"), BER_BVC("sn") },
     62 	{ BER_BVC("2.5.4.6"), BER_BVC("c") },
     63 	{ BER_BVC("2.5.4.7"), BER_BVC("l") },
     64 	{ BER_BVC("2.5.4.8"), BER_BVC("st") },
     65 	{ BER_BVC("2.5.4.10"), BER_BVC("o") },
     66 	{ BER_BVC("2.5.4.11"), BER_BVC("ou") },
     67 	{ BER_BVC("2.5.4.12"), BER_BVC("title") },
     68 	{ BER_BVC("2.5.4.41"), BER_BVC("name") },
     69 	{ BER_BVC("2.5.4.42"), BER_BVC("givenName") },
     70 	{ BER_BVC("2.5.4.43"), BER_BVC("initials") },
     71 	{ BER_BVC("2.5.4.44"), BER_BVC("generationQualifier") },
     72 	{ BER_BVC("2.5.4.46"), BER_BVC("dnQualifier") },
     73 	{ BER_BVC("1.2.840.113549.1.9.1"), BER_BVC("email") },
     74 	{ BER_BVC("0.9.2342.19200300.100.1.25"), BER_BVC("dc") },
     75 	{ BER_BVNULL, BER_BVNULL }
     76 };
     77 
     78 #ifdef HAVE_TLS
     79 
     80 LDAP_F(int) ldap_pvt_tls_check_hostname LDAP_P(( LDAP *ld, void *s, const char *name_in ));
     81 LDAP_F(int) ldap_pvt_tls_get_peercert LDAP_P(( void *s, struct berval *der ));
     82 
     83 void
     84 ldap_pvt_tls_ctx_free ( void *c )
     85 {
     86 	if ( !c ) return;
     87 	tls_imp->ti_ctx_free( c );
     88 }
     89 
     90 static void
     91 tls_ctx_ref( tls_ctx *ctx )
     92 {
     93 	if ( !ctx ) return;
     94 
     95 	tls_imp->ti_ctx_ref( ctx );
     96 }
     97 
     98 #ifdef LDAP_R_COMPILE
     99 /*
    100  * an extra mutex for the default ctx.
    101  */
    102 static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
    103 #endif
    104 
    105 void
    106 ldap_int_tls_destroy( struct ldapoptions *lo )
    107 {
    108 	if ( lo->ldo_tls_ctx ) {
    109 		ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
    110 		lo->ldo_tls_ctx = NULL;
    111 	}
    112 
    113 	if ( lo->ldo_tls_certfile ) {
    114 		LDAP_FREE( lo->ldo_tls_certfile );
    115 		lo->ldo_tls_certfile = NULL;
    116 	}
    117 	if ( lo->ldo_tls_keyfile ) {
    118 		LDAP_FREE( lo->ldo_tls_keyfile );
    119 		lo->ldo_tls_keyfile = NULL;
    120 	}
    121 	if ( lo->ldo_tls_dhfile ) {
    122 		LDAP_FREE( lo->ldo_tls_dhfile );
    123 		lo->ldo_tls_dhfile = NULL;
    124 	}
    125 	if ( lo->ldo_tls_ecname ) {
    126 		LDAP_FREE( lo->ldo_tls_ecname );
    127 		lo->ldo_tls_ecname = NULL;
    128 	}
    129 	if ( lo->ldo_tls_cacertfile ) {
    130 		LDAP_FREE( lo->ldo_tls_cacertfile );
    131 		lo->ldo_tls_cacertfile = NULL;
    132 	}
    133 	if ( lo->ldo_tls_cacertdir ) {
    134 		LDAP_FREE( lo->ldo_tls_cacertdir );
    135 		lo->ldo_tls_cacertdir = NULL;
    136 	}
    137 	if ( lo->ldo_tls_ciphersuite ) {
    138 		LDAP_FREE( lo->ldo_tls_ciphersuite );
    139 		lo->ldo_tls_ciphersuite = NULL;
    140 	}
    141 	if ( lo->ldo_tls_crlfile ) {
    142 		LDAP_FREE( lo->ldo_tls_crlfile );
    143 		lo->ldo_tls_crlfile = NULL;
    144 	}
    145 	/* tls_pin_hashalg and tls_pin share the same buffer */
    146 	if ( lo->ldo_tls_pin_hashalg ) {
    147 		LDAP_FREE( lo->ldo_tls_pin_hashalg );
    148 		lo->ldo_tls_pin_hashalg = NULL;
    149 	} else {
    150 		LDAP_FREE( lo->ldo_tls_pin.bv_val );
    151 	}
    152 	BER_BVZERO( &lo->ldo_tls_pin );
    153 }
    154 
    155 /*
    156  * Tear down the TLS subsystem. Should only be called once.
    157  */
    158 void
    159 ldap_pvt_tls_destroy( void )
    160 {
    161 	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
    162 
    163 	ldap_int_tls_destroy( lo );
    164 
    165 	tls_imp->ti_tls_destroy();
    166 }
    167 
    168 /*
    169  * Initialize a particular TLS implementation.
    170  * Called once per implementation.
    171  */
    172 static int
    173 tls_init(tls_impl *impl, int do_threads )
    174 {
    175 	static int tls_initialized = 0;
    176 
    177 	if ( !tls_initialized++ ) {
    178 #ifdef LDAP_R_COMPILE
    179 		ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
    180 #endif
    181 	}
    182 
    183 	if ( impl->ti_inited++ ) return 0;
    184 
    185 	if ( do_threads ) {
    186 #ifdef LDAP_R_COMPILE
    187 		impl->ti_thr_init();
    188 #endif
    189 	}
    190 
    191 	return impl->ti_tls_init();
    192 }
    193 
    194 /*
    195  * Initialize TLS subsystem. Called once per implementation.
    196  */
    197 int
    198 ldap_pvt_tls_init( int do_threads )
    199 {
    200 	return tls_init( tls_imp, do_threads );
    201 }
    202 
    203 /*
    204  * initialize a new TLS context
    205  */
    206 static int
    207 ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server, char *errmsg )
    208 {
    209 	int rc = 0;
    210 	tls_impl *ti = tls_imp;
    211 	struct ldaptls lts = lo->ldo_tls_info;
    212 
    213 	if ( lo->ldo_tls_ctx )
    214 		return 0;
    215 
    216 	tls_init( ti, 0 );
    217 
    218 	if ( is_server && !lts.lt_certfile && !lts.lt_keyfile &&
    219 		!lts.lt_cacertfile && !lts.lt_cacertdir &&
    220 		!lts.lt_cacert.bv_val && !lts.lt_cert.bv_val &&
    221 		!lts.lt_key.bv_val ) {
    222 		/* minimum configuration not provided */
    223 		return LDAP_NOT_SUPPORTED;
    224 	}
    225 
    226 #ifdef HAVE_EBCDIC
    227 	/* This ASCII/EBCDIC handling is a real pain! */
    228 	if ( lts.lt_ciphersuite ) {
    229 		lts.lt_ciphersuite = LDAP_STRDUP( lts.lt_ciphersuite );
    230 		__atoe( lts.lt_ciphersuite );
    231 	}
    232 	if ( lts.lt_cacertfile ) {
    233 		lts.lt_cacertfile = LDAP_STRDUP( lts.lt_cacertfile );
    234 		__atoe( lts.lt_cacertfile );
    235 	}
    236 	if ( lts.lt_certfile ) {
    237 		lts.lt_certfile = LDAP_STRDUP( lts.lt_certfile );
    238 		__atoe( lts.lt_certfile );
    239 	}
    240 	if ( lts.lt_keyfile ) {
    241 		lts.lt_keyfile = LDAP_STRDUP( lts.lt_keyfile );
    242 		__atoe( lts.lt_keyfile );
    243 	}
    244 	if ( lts.lt_crlfile ) {
    245 		lts.lt_crlfile = LDAP_STRDUP( lts.lt_crlfile );
    246 		__atoe( lts.lt_crlfile );
    247 	}
    248 	if ( lts.lt_cacertdir ) {
    249 		lts.lt_cacertdir = LDAP_STRDUP( lts.lt_cacertdir );
    250 		__atoe( lts.lt_cacertdir );
    251 	}
    252 	if ( lts.lt_dhfile ) {
    253 		lts.lt_dhfile = LDAP_STRDUP( lts.lt_dhfile );
    254 		__atoe( lts.lt_dhfile );
    255 	}
    256 	if ( lts.lt_ecname ) {
    257 		lts.lt_ecname = LDAP_STRDUP( lts.lt_ecname );
    258 		__atoe( lts.lt_ecname );
    259 	}
    260 #endif
    261 	lo->ldo_tls_ctx = ti->ti_ctx_new( lo );
    262 	if ( lo->ldo_tls_ctx == NULL ) {
    263 		Debug0( LDAP_DEBUG_ANY,
    264 		   "TLS: could not allocate default ctx.\n" );
    265 		rc = -1;
    266 		goto error_exit;
    267 	}
    268 
    269 	rc = ti->ti_ctx_init( lo, &lts, is_server, errmsg );
    270 
    271 error_exit:
    272 	if ( rc < 0 && lo->ldo_tls_ctx != NULL ) {
    273 		ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
    274 		lo->ldo_tls_ctx = NULL;
    275 	}
    276 #ifdef HAVE_EBCDIC
    277 	LDAP_FREE( lts.lt_ciphersuite );
    278 	LDAP_FREE( lts.lt_cacertfile );
    279 	LDAP_FREE( lts.lt_certfile );
    280 	LDAP_FREE( lts.lt_keyfile );
    281 	LDAP_FREE( lts.lt_crlfile );
    282 	LDAP_FREE( lts.lt_cacertdir );
    283 	LDAP_FREE( lts.lt_dhfile );
    284 	LDAP_FREE( lts.lt_ecname );
    285 #endif
    286 	return rc;
    287 }
    288 
    289 /*
    290  * initialize the default context
    291  */
    292 int
    293 ldap_pvt_tls_init_def_ctx( int is_server )
    294 {
    295 	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
    296 	char errmsg[ERRBUFSIZE];
    297 	int rc;
    298 	errmsg[0] = 0;
    299 	LDAP_MUTEX_LOCK( &tls_def_ctx_mutex );
    300 	rc = ldap_int_tls_init_ctx( lo, is_server, errmsg );
    301 	LDAP_MUTEX_UNLOCK( &tls_def_ctx_mutex );
    302 	if ( rc ) {
    303 		Debug1( LDAP_DEBUG_ANY,"TLS: init_def_ctx: %s.\n", errmsg );
    304 	}
    305 	return rc;
    306 }
    307 
    308 static tls_session *
    309 alloc_handle( void *ctx_arg, int is_server )
    310 {
    311 	tls_ctx	*ctx;
    312 	tls_session	*ssl;
    313 
    314 	if ( ctx_arg ) {
    315 		ctx = ctx_arg;
    316 	} else {
    317 		struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
    318 		if ( ldap_pvt_tls_init_def_ctx( is_server ) < 0 ) return NULL;
    319 		ctx = lo->ldo_tls_ctx;
    320 	}
    321 
    322 	ssl = tls_imp->ti_session_new( ctx, is_server );
    323 	if ( ssl == NULL ) {
    324 		Debug0( LDAP_DEBUG_ANY,"TLS: can't create ssl handle.\n" );
    325 		return NULL;
    326 	}
    327 	return ssl;
    328 }
    329 
    330 static int
    331 update_flags( Sockbuf *sb, tls_session * ssl, int rc )
    332 {
    333 	sb->sb_trans_needs_read  = 0;
    334 	sb->sb_trans_needs_write = 0;
    335 
    336 	return tls_imp->ti_session_upflags( sb, ssl, rc );
    337 }
    338 
    339 /*
    340  * Call this to do a TLS connect on a sockbuf. ctx_arg can be
    341  * a SSL_CTX * or NULL, in which case the default ctx is used.
    342  *
    343  * Return value:
    344  *
    345  *  0 - Success. Connection is ready for communication.
    346  * <0 - Error. Can't create a TLS stream.
    347  * >0 - Partial success.
    348  *	  Do a select (using information from lber_pvt_sb_needs_{read,write}
    349  *		and call again.
    350  */
    351 
    352 static int
    353 ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host )
    354 {
    355 	Sockbuf *sb = conn->lconn_sb;
    356 	int	err;
    357 	tls_session	*ssl = NULL;
    358 	const char *sni = host;
    359 
    360 	if ( HAS_TLS( sb )) {
    361 		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
    362 	} else {
    363 		struct ldapoptions *lo;
    364 		tls_ctx *ctx;
    365 
    366 		ctx = ld->ld_options.ldo_tls_ctx;
    367 
    368 		ssl = alloc_handle( ctx, 0 );
    369 
    370 		if ( ssl == NULL ) return -1;
    371 
    372 #ifdef LDAP_DEBUG
    373 		ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
    374 			LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
    375 #endif
    376 		ber_sockbuf_add_io( sb, tls_imp->ti_sbio,
    377 			LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
    378 
    379 		lo = LDAP_INT_GLOBAL_OPT();
    380 		if( ctx == NULL ) {
    381 			ctx = lo->ldo_tls_ctx;
    382 			ld->ld_options.ldo_tls_ctx = ctx;
    383 			tls_ctx_ref( ctx );
    384 		}
    385 		if ( ld->ld_options.ldo_tls_connect_cb )
    386 			ld->ld_options.ldo_tls_connect_cb( ld, ssl, ctx,
    387 			ld->ld_options.ldo_tls_connect_arg );
    388 		if ( lo && lo->ldo_tls_connect_cb && lo->ldo_tls_connect_cb !=
    389 			ld->ld_options.ldo_tls_connect_cb )
    390 			lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
    391 		conn->lconn_status = LDAP_CONNST_TLS_INPROGRESS;
    392 	}
    393 
    394 	/* pass hostname for SNI, but only if it's an actual name
    395 	 * and not a numeric address
    396 	 */
    397 	{
    398 		int numeric = 1;
    399 		unsigned char *c;
    400 		for ( c = (unsigned char *)sni; *c; c++ ) {
    401 			if ( *c == ':' )	/* IPv6 address */
    402 				break;
    403 			if ( *c == '.' )
    404 				continue;
    405 			if ( !isdigit( (unsigned char)*c )) {
    406 				numeric = 0;
    407 				break;
    408 			}
    409 		}
    410 		if ( numeric )
    411 			sni = NULL;
    412 	}
    413 	err = tls_imp->ti_session_connect( ld, ssl, sni );
    414 
    415 #ifdef HAVE_WINSOCK
    416 	errno = WSAGetLastError();
    417 #endif
    418 
    419 	if ( err == 0 ) {
    420 		err = ldap_pvt_tls_check_hostname( ld, ssl, host );
    421 	}
    422 
    423 	if ( err < 0 )
    424 	{
    425 		char buf[256], *msg;
    426 		if ( update_flags( sb, ssl, err )) {
    427 			return 1;
    428 		}
    429 
    430 		msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
    431 		if ( msg ) {
    432 			if ( ld->ld_error ) {
    433 				LDAP_FREE( ld->ld_error );
    434 			}
    435 			ld->ld_error = LDAP_STRDUP( msg );
    436 #ifdef HAVE_EBCDIC
    437 			if ( ld->ld_error ) __etoa(ld->ld_error);
    438 #endif
    439 		}
    440 
    441 		Debug1( LDAP_DEBUG_ANY,"TLS: can't connect: %s.\n",
    442 			ld->ld_error ? ld->ld_error : "" );
    443 
    444 		ber_sockbuf_remove_io( sb, tls_imp->ti_sbio,
    445 			LBER_SBIOD_LEVEL_TRANSPORT );
    446 #ifdef LDAP_DEBUG
    447 		ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
    448 			LBER_SBIOD_LEVEL_TRANSPORT );
    449 #endif
    450 		conn->lconn_status = LDAP_CONNST_CONNECTED;
    451 		return -1;
    452 	}
    453 
    454 	conn->lconn_status = LDAP_CONNST_CONNECTED;
    455 	return 0;
    456 }
    457 
    458 int
    459 ldap_pvt_tls_connect( LDAP *ld, Sockbuf *sb, const char *host )
    460 {
    461 	LDAPConn conn = { .lconn_sb = sb };
    462 	return ldap_int_tls_connect( ld, &conn, host );
    463 }
    464 
    465 /*
    466  * Call this to do a TLS accept on a sockbuf.
    467  * Everything else is the same as with tls_connect.
    468  */
    469 int
    470 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
    471 {
    472 	int	err;
    473 	tls_session	*ssl = NULL;
    474 
    475 	if ( HAS_TLS( sb )) {
    476 		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
    477 	} else {
    478 		ssl = alloc_handle( ctx_arg, 1 );
    479 		if ( ssl == NULL ) return -1;
    480 
    481 #ifdef LDAP_DEBUG
    482 		ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
    483 			LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
    484 #endif
    485 		ber_sockbuf_add_io( sb, tls_imp->ti_sbio,
    486 			LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
    487 	}
    488 
    489 	err = tls_imp->ti_session_accept( ssl );
    490 
    491 #ifdef HAVE_WINSOCK
    492 	errno = WSAGetLastError();
    493 #endif
    494 
    495 	if ( err < 0 )
    496 	{
    497 		if ( update_flags( sb, ssl, err )) return 1;
    498 
    499 		if ( DebugTest( LDAP_DEBUG_ANY ) ) {
    500 			char buf[256], *msg;
    501 			msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
    502 			Debug1( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n",
    503 				msg ? msg : "(unknown)" );
    504 		}
    505 
    506 		ber_sockbuf_remove_io( sb, tls_imp->ti_sbio,
    507 			LBER_SBIOD_LEVEL_TRANSPORT );
    508 #ifdef LDAP_DEBUG
    509 		ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
    510 			LBER_SBIOD_LEVEL_TRANSPORT );
    511 #endif
    512 		return -1;
    513 	}
    514 	return 0;
    515 }
    516 
    517 int
    518 ldap_pvt_tls_inplace ( Sockbuf *sb )
    519 {
    520 	return HAS_TLS( sb ) ? 1 : 0;
    521 }
    522 
    523 int
    524 ldap_tls_inplace( LDAP *ld )
    525 {
    526 	Sockbuf		*sb = NULL;
    527 	LDAPConn	*lc = ld->ld_defconn;
    528 
    529 	if ( lc && lc->lconn_sb ) {
    530 		sb = ld->ld_defconn->lconn_sb;
    531 
    532 	} else if ( ld->ld_sb ) {
    533 		sb = ld->ld_sb;
    534 
    535 	} else {
    536 		return 0;
    537 	}
    538 
    539 	if ( lc && lc->lconn_status == LDAP_CONNST_TLS_INPROGRESS ) {
    540 		return 0;
    541 	}
    542 
    543 	return ldap_pvt_tls_inplace( sb );
    544 }
    545 
    546 int
    547 ldap_pvt_tls_get_peer_dn( void *s, struct berval *dn,
    548 	LDAPDN_rewrite_dummy *func, unsigned flags )
    549 {
    550 	tls_session *session = s;
    551 	struct berval bvdn;
    552 	int rc;
    553 
    554 	rc = tls_imp->ti_session_peer_dn( session, &bvdn );
    555 	if ( rc ) return rc;
    556 
    557 	rc = ldap_X509dn2bv( &bvdn, dn,
    558 			    (LDAPDN_rewrite_func *)func, flags);
    559 	return rc;
    560 }
    561 
    562 int
    563 ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
    564 {
    565 	tls_session *session = s;
    566 
    567 	if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER &&
    568 	    ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) {
    569 		ld->ld_errno = tls_imp->ti_session_chkhost( ld, session, name_in );
    570 		if (ld->ld_errno != LDAP_SUCCESS) {
    571 			return ld->ld_errno;
    572 		}
    573 	}
    574 
    575 	/*
    576 	 * If instructed to do pinning, do it now
    577 	 */
    578 	if ( !BER_BVISNULL( &ld->ld_options.ldo_tls_pin ) ) {
    579 		ld->ld_errno = tls_imp->ti_session_pinning( ld, s,
    580 				ld->ld_options.ldo_tls_pin_hashalg,
    581 				&ld->ld_options.ldo_tls_pin );
    582 		if (ld->ld_errno != LDAP_SUCCESS) {
    583 			return ld->ld_errno;
    584 		}
    585 	}
    586 
    587 	return LDAP_SUCCESS;
    588 }
    589 
    590 int
    591 ldap_pvt_tls_config( LDAP *ld, int option, const char *arg )
    592 {
    593 	int i;
    594 
    595 	switch( option ) {
    596 	case LDAP_OPT_X_TLS_CACERTFILE:
    597 	case LDAP_OPT_X_TLS_CACERTDIR:
    598 	case LDAP_OPT_X_TLS_CERTFILE:
    599 	case LDAP_OPT_X_TLS_KEYFILE:
    600 	case LDAP_OPT_X_TLS_RANDOM_FILE:
    601 	case LDAP_OPT_X_TLS_CIPHER_SUITE:
    602 	case LDAP_OPT_X_TLS_DHFILE:
    603 	case LDAP_OPT_X_TLS_PEERKEY_HASH:
    604 	case LDAP_OPT_X_TLS_ECNAME:
    605 	case LDAP_OPT_X_TLS_CRLFILE:	/* GnuTLS only */
    606 		return ldap_pvt_tls_set_option( ld, option, (void *) arg );
    607 
    608 	case LDAP_OPT_X_TLS_REQUIRE_CERT:
    609 	case LDAP_OPT_X_TLS_REQUIRE_SAN:
    610 	case LDAP_OPT_X_TLS:
    611 		i = -1;
    612 		if ( strcasecmp( arg, "never" ) == 0 ) {
    613 			i = LDAP_OPT_X_TLS_NEVER ;
    614 
    615 		} else if ( strcasecmp( arg, "demand" ) == 0 ) {
    616 			i = LDAP_OPT_X_TLS_DEMAND ;
    617 
    618 		} else if ( strcasecmp( arg, "allow" ) == 0 ) {
    619 			i = LDAP_OPT_X_TLS_ALLOW ;
    620 
    621 		} else if ( strcasecmp( arg, "try" ) == 0 ) {
    622 			i = LDAP_OPT_X_TLS_TRY ;
    623 
    624 		} else if ( ( strcasecmp( arg, "hard" ) == 0 ) ||
    625 			( strcasecmp( arg, "on" ) == 0 ) ||
    626 			( strcasecmp( arg, "yes" ) == 0) ||
    627 			( strcasecmp( arg, "true" ) == 0 ) )
    628 		{
    629 			i = LDAP_OPT_X_TLS_HARD ;
    630 		}
    631 
    632 		if (i >= 0) {
    633 			return ldap_pvt_tls_set_option( ld, option, &i );
    634 		}
    635 		return -1;
    636 	case LDAP_OPT_X_TLS_PROTOCOL_MAX:
    637 	case LDAP_OPT_X_TLS_PROTOCOL_MIN: {
    638 		char *next;
    639 		long l;
    640 		l = strtol( arg, &next, 10 );
    641 		if ( l < 0 || l > 0xff || next == arg ||
    642 			( *next != '\0' && *next != '.' ) )
    643 			return -1;
    644 		i = l << 8;
    645 		if (*next == '.') {
    646 			arg = next + 1;
    647 			l = strtol( arg, &next, 10 );
    648 			if ( l < 0 || l > 0xff || next == arg || *next != '\0' )
    649 				return -1;
    650 			i += l;
    651 		}
    652 		return ldap_pvt_tls_set_option( ld, option, &i );
    653 		}
    654 #ifdef HAVE_OPENSSL
    655 	case LDAP_OPT_X_TLS_CRLCHECK:	/* OpenSSL only */
    656 		i = -1;
    657 		if ( strcasecmp( arg, "none" ) == 0 ) {
    658 			i = LDAP_OPT_X_TLS_CRL_NONE ;
    659 		} else if ( strcasecmp( arg, "peer" ) == 0 ) {
    660 			i = LDAP_OPT_X_TLS_CRL_PEER ;
    661 		} else if ( strcasecmp( arg, "all" ) == 0 ) {
    662 			i = LDAP_OPT_X_TLS_CRL_ALL ;
    663 		}
    664 		if (i >= 0) {
    665 			return ldap_pvt_tls_set_option( ld, option, &i );
    666 		}
    667 		return -1;
    668 #endif
    669 	}
    670 	return -1;
    671 }
    672 
    673 int
    674 ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
    675 {
    676 	struct ldapoptions *lo;
    677 
    678 	if( option == LDAP_OPT_X_TLS_PACKAGE ) {
    679 		*(char **)arg = LDAP_STRDUP( tls_imp->ti_name );
    680 		return 0;
    681 	}
    682 
    683 	if( ld != NULL ) {
    684 		assert( LDAP_VALID( ld ) );
    685 
    686 		if( !LDAP_VALID( ld ) ) {
    687 			return LDAP_OPT_ERROR;
    688 		}
    689 
    690 		lo = &ld->ld_options;
    691 
    692 	} else {
    693 		/* Get pointer to global option structure */
    694 		lo = LDAP_INT_GLOBAL_OPT();
    695 		if ( lo == NULL ) {
    696 			return LDAP_NO_MEMORY;
    697 		}
    698 	}
    699 
    700 	switch( option ) {
    701 	case LDAP_OPT_X_TLS:
    702 		*(int *)arg = lo->ldo_tls_mode;
    703 		break;
    704 	case LDAP_OPT_X_TLS_CTX:
    705 		*(void **)arg = lo->ldo_tls_ctx;
    706 		if ( lo->ldo_tls_ctx ) {
    707 			tls_ctx_ref( lo->ldo_tls_ctx );
    708 		}
    709 		break;
    710 	case LDAP_OPT_X_TLS_CACERTFILE:
    711 		*(char **)arg = lo->ldo_tls_cacertfile ?
    712 			LDAP_STRDUP( lo->ldo_tls_cacertfile ) : NULL;
    713 		break;
    714 	case LDAP_OPT_X_TLS_CACERTDIR:
    715 		*(char **)arg = lo->ldo_tls_cacertdir ?
    716 			LDAP_STRDUP( lo->ldo_tls_cacertdir ) : NULL;
    717 		break;
    718 	case LDAP_OPT_X_TLS_CERTFILE:
    719 		*(char **)arg = lo->ldo_tls_certfile ?
    720 			LDAP_STRDUP( lo->ldo_tls_certfile ) : NULL;
    721 		break;
    722 	case LDAP_OPT_X_TLS_KEYFILE:
    723 		*(char **)arg = lo->ldo_tls_keyfile ?
    724 			LDAP_STRDUP( lo->ldo_tls_keyfile ) : NULL;
    725 		break;
    726 	case LDAP_OPT_X_TLS_DHFILE:
    727 		*(char **)arg = lo->ldo_tls_dhfile ?
    728 			LDAP_STRDUP( lo->ldo_tls_dhfile ) : NULL;
    729 		break;
    730 	case LDAP_OPT_X_TLS_ECNAME:
    731 		*(char **)arg = lo->ldo_tls_ecname ?
    732 			LDAP_STRDUP( lo->ldo_tls_ecname ) : NULL;
    733 		break;
    734 	case LDAP_OPT_X_TLS_CRLFILE:	/* GnuTLS only */
    735 		*(char **)arg = lo->ldo_tls_crlfile ?
    736 			LDAP_STRDUP( lo->ldo_tls_crlfile ) : NULL;
    737 		break;
    738 	case LDAP_OPT_X_TLS_REQUIRE_CERT:
    739 		*(int *)arg = lo->ldo_tls_require_cert;
    740 		break;
    741 	case LDAP_OPT_X_TLS_REQUIRE_SAN:
    742 		*(int *)arg = lo->ldo_tls_require_san;
    743 		break;
    744 #ifdef HAVE_OPENSSL
    745 	case LDAP_OPT_X_TLS_CRLCHECK:	/* OpenSSL only */
    746 		*(int *)arg = lo->ldo_tls_crlcheck;
    747 		break;
    748 #endif
    749 	case LDAP_OPT_X_TLS_CIPHER_SUITE:
    750 		*(char **)arg = lo->ldo_tls_ciphersuite ?
    751 			LDAP_STRDUP( lo->ldo_tls_ciphersuite ) : NULL;
    752 		break;
    753 	case LDAP_OPT_X_TLS_PROTOCOL_MIN:
    754 		*(int *)arg = lo->ldo_tls_protocol_min;
    755 		break;
    756 	case LDAP_OPT_X_TLS_PROTOCOL_MAX:
    757 		*(int *)arg = lo->ldo_tls_protocol_max;
    758 		break;
    759 	case LDAP_OPT_X_TLS_RANDOM_FILE:
    760 		*(char **)arg = lo->ldo_tls_randfile ?
    761 			LDAP_STRDUP( lo->ldo_tls_randfile ) : NULL;
    762 		break;
    763 	case LDAP_OPT_X_TLS_SSL_CTX: {
    764 		void *retval = 0;
    765 		if ( ld != NULL ) {
    766 			LDAPConn *conn = ld->ld_defconn;
    767 			if ( conn != NULL ) {
    768 				Sockbuf *sb = conn->lconn_sb;
    769 				retval = ldap_pvt_tls_sb_ctx( sb );
    770 			}
    771 		}
    772 		*(void **)arg = retval;
    773 		break;
    774 	}
    775 	case LDAP_OPT_X_TLS_CONNECT_CB:
    776 		*(LDAP_TLS_CONNECT_CB **)arg = lo->ldo_tls_connect_cb;
    777 		break;
    778 	case LDAP_OPT_X_TLS_CONNECT_ARG:
    779 		*(void **)arg = lo->ldo_tls_connect_arg;
    780 		break;
    781 	case LDAP_OPT_X_TLS_VERSION: {
    782 		void *sess = NULL;
    783 		const char *retval = NULL;
    784 		if ( ld != NULL ) {
    785 			LDAPConn *conn = ld->ld_defconn;
    786 			if ( conn != NULL ) {
    787 				Sockbuf *sb = conn->lconn_sb;
    788 				sess = ldap_pvt_tls_sb_ctx( sb );
    789 				if ( sess != NULL )
    790 					retval = ldap_pvt_tls_get_version( sess );
    791 			}
    792 		}
    793 		*(char **)arg = retval ? LDAP_STRDUP( retval ) : NULL;
    794 		break;
    795 	}
    796 	case LDAP_OPT_X_TLS_CIPHER: {
    797 		void *sess = NULL;
    798 		const char *retval = NULL;
    799 		if ( ld != NULL ) {
    800 			LDAPConn *conn = ld->ld_defconn;
    801 			if ( conn != NULL ) {
    802 				Sockbuf *sb = conn->lconn_sb;
    803 				sess = ldap_pvt_tls_sb_ctx( sb );
    804 				if ( sess != NULL )
    805 					retval = ldap_pvt_tls_get_cipher( sess );
    806 			}
    807 		}
    808 		*(char **)arg = retval ? LDAP_STRDUP( retval ) : NULL;
    809 		break;
    810 	}
    811 	case LDAP_OPT_X_TLS_PEERCERT: {
    812 		void *sess = NULL;
    813 		struct berval *bv = arg;
    814 		bv->bv_len = 0;
    815 		bv->bv_val = NULL;
    816 		if ( ld != NULL ) {
    817 			LDAPConn *conn = ld->ld_defconn;
    818 			if ( conn != NULL ) {
    819 				Sockbuf *sb = conn->lconn_sb;
    820 				sess = ldap_pvt_tls_sb_ctx( sb );
    821 				if ( sess != NULL )
    822 					return ldap_pvt_tls_get_peercert( sess, bv );
    823 			}
    824 		}
    825 		break;
    826 	}
    827 	case LDAP_OPT_X_TLS_CACERT: {
    828 		struct berval *bv = arg;
    829 		if ( lo->ldo_tls_cacert.bv_val ) {
    830 			ber_dupbv( bv, &lo->ldo_tls_cacert );
    831 		} else {
    832 			BER_BVZERO( bv );
    833 		}
    834 		break;
    835 	}
    836 	case LDAP_OPT_X_TLS_CERT: {
    837 		struct berval *bv = arg;
    838 		if ( lo->ldo_tls_cert.bv_val ) {
    839 			ber_dupbv( bv, &lo->ldo_tls_cert );
    840 		} else {
    841 			BER_BVZERO( bv );
    842 		}
    843 		break;
    844 	}
    845 	case LDAP_OPT_X_TLS_KEY: {
    846 		struct berval *bv = arg;
    847 		if ( lo->ldo_tls_key.bv_val ) {
    848 			ber_dupbv( bv, &lo->ldo_tls_key );
    849 		} else {
    850 			BER_BVZERO( bv );
    851 		}
    852 		break;
    853 	}
    854 
    855 	default:
    856 		return -1;
    857 	}
    858 	return 0;
    859 }
    860 
    861 int
    862 ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
    863 {
    864 	struct ldapoptions *lo;
    865 
    866 	if( ld != NULL ) {
    867 		assert( LDAP_VALID( ld ) );
    868 
    869 		if( !LDAP_VALID( ld ) ) {
    870 			return LDAP_OPT_ERROR;
    871 		}
    872 
    873 		lo = &ld->ld_options;
    874 
    875 	} else {
    876 		/* Get pointer to global option structure */
    877 		lo = LDAP_INT_GLOBAL_OPT();
    878 		if ( lo == NULL ) {
    879 			return LDAP_NO_MEMORY;
    880 		}
    881 	}
    882 
    883 	switch( option ) {
    884 	case LDAP_OPT_X_TLS:
    885 		if ( !arg ) return -1;
    886 
    887 		switch( *(int *) arg ) {
    888 		case LDAP_OPT_X_TLS_NEVER:
    889 		case LDAP_OPT_X_TLS_DEMAND:
    890 		case LDAP_OPT_X_TLS_ALLOW:
    891 		case LDAP_OPT_X_TLS_TRY:
    892 		case LDAP_OPT_X_TLS_HARD:
    893 			if (lo != NULL) {
    894 				lo->ldo_tls_mode = *(int *)arg;
    895 			}
    896 
    897 			return 0;
    898 		}
    899 		return -1;
    900 
    901 	case LDAP_OPT_X_TLS_CTX:
    902 		if ( lo->ldo_tls_ctx )
    903 			ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
    904 		lo->ldo_tls_ctx = arg;
    905 		tls_ctx_ref( lo->ldo_tls_ctx );
    906 		return 0;
    907 	case LDAP_OPT_X_TLS_CONNECT_CB:
    908 		lo->ldo_tls_connect_cb = (LDAP_TLS_CONNECT_CB *)arg;
    909 		return 0;
    910 	case LDAP_OPT_X_TLS_CONNECT_ARG:
    911 		lo->ldo_tls_connect_arg = arg;
    912 		return 0;
    913 	case LDAP_OPT_X_TLS_CACERTFILE:
    914 		if ( lo->ldo_tls_cacertfile ) LDAP_FREE( lo->ldo_tls_cacertfile );
    915 		lo->ldo_tls_cacertfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    916 		return 0;
    917 	case LDAP_OPT_X_TLS_CACERTDIR:
    918 		if ( lo->ldo_tls_cacertdir ) LDAP_FREE( lo->ldo_tls_cacertdir );
    919 		lo->ldo_tls_cacertdir = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    920 		return 0;
    921 	case LDAP_OPT_X_TLS_CERTFILE:
    922 		if ( lo->ldo_tls_certfile ) LDAP_FREE( lo->ldo_tls_certfile );
    923 		lo->ldo_tls_certfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    924 		return 0;
    925 	case LDAP_OPT_X_TLS_KEYFILE:
    926 		if ( lo->ldo_tls_keyfile ) LDAP_FREE( lo->ldo_tls_keyfile );
    927 		lo->ldo_tls_keyfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    928 		return 0;
    929 	case LDAP_OPT_X_TLS_DHFILE:
    930 		if ( lo->ldo_tls_dhfile ) LDAP_FREE( lo->ldo_tls_dhfile );
    931 		lo->ldo_tls_dhfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    932 		return 0;
    933 	case LDAP_OPT_X_TLS_ECNAME:
    934 		if ( lo->ldo_tls_ecname ) LDAP_FREE( lo->ldo_tls_ecname );
    935 		lo->ldo_tls_ecname = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    936 		return 0;
    937 	case LDAP_OPT_X_TLS_CRLFILE:	/* GnuTLS only */
    938 		if ( lo->ldo_tls_crlfile ) LDAP_FREE( lo->ldo_tls_crlfile );
    939 		lo->ldo_tls_crlfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    940 		return 0;
    941 	case LDAP_OPT_X_TLS_REQUIRE_CERT:
    942 		if ( !arg ) return -1;
    943 		switch( *(int *) arg ) {
    944 		case LDAP_OPT_X_TLS_NEVER:
    945 		case LDAP_OPT_X_TLS_DEMAND:
    946 		case LDAP_OPT_X_TLS_ALLOW:
    947 		case LDAP_OPT_X_TLS_TRY:
    948 		case LDAP_OPT_X_TLS_HARD:
    949 			lo->ldo_tls_require_cert = * (int *) arg;
    950 			return 0;
    951 		}
    952 		return -1;
    953 	case LDAP_OPT_X_TLS_REQUIRE_SAN:
    954 		if ( !arg ) return -1;
    955 		switch( *(int *) arg ) {
    956 		case LDAP_OPT_X_TLS_NEVER:
    957 		case LDAP_OPT_X_TLS_DEMAND:
    958 		case LDAP_OPT_X_TLS_ALLOW:
    959 		case LDAP_OPT_X_TLS_TRY:
    960 		case LDAP_OPT_X_TLS_HARD:
    961 			lo->ldo_tls_require_san = * (int *) arg;
    962 			return 0;
    963 		}
    964 		return -1;
    965 #ifdef HAVE_OPENSSL
    966 	case LDAP_OPT_X_TLS_CRLCHECK:	/* OpenSSL only */
    967 		if ( !arg ) return -1;
    968 		switch( *(int *) arg ) {
    969 		case LDAP_OPT_X_TLS_CRL_NONE:
    970 		case LDAP_OPT_X_TLS_CRL_PEER:
    971 		case LDAP_OPT_X_TLS_CRL_ALL:
    972 			lo->ldo_tls_crlcheck = * (int *) arg;
    973 			return 0;
    974 		}
    975 		return -1;
    976 #endif
    977 	case LDAP_OPT_X_TLS_CIPHER_SUITE:
    978 		if ( lo->ldo_tls_ciphersuite ) LDAP_FREE( lo->ldo_tls_ciphersuite );
    979 		lo->ldo_tls_ciphersuite = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    980 		return 0;
    981 
    982 	case LDAP_OPT_X_TLS_PROTOCOL_MIN:
    983 		if ( !arg ) return -1;
    984 		lo->ldo_tls_protocol_min = *(int *)arg;
    985 		return 0;
    986 	case LDAP_OPT_X_TLS_PROTOCOL_MAX:
    987 		if ( !arg ) return -1;
    988 		lo->ldo_tls_protocol_max = *(int *)arg;
    989 		return 0;
    990 	case LDAP_OPT_X_TLS_RANDOM_FILE:
    991 		if ( ld != NULL )
    992 			return -1;
    993 		if ( lo->ldo_tls_randfile ) LDAP_FREE (lo->ldo_tls_randfile );
    994 		lo->ldo_tls_randfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
    995 		break;
    996 	case LDAP_OPT_X_TLS_NEWCTX: {
    997 		int rc;
    998 		char errmsg[ERRBUFSIZE];
    999 		if ( !arg ) return -1;
   1000 		if ( lo->ldo_tls_ctx )
   1001 			ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
   1002 		lo->ldo_tls_ctx = NULL;
   1003 		errmsg[0] = 0;
   1004 		rc = ldap_int_tls_init_ctx( lo, *(int *)arg, errmsg );
   1005 		if ( rc && errmsg[0] && ld ) {
   1006 			if ( ld->ld_error )
   1007 				LDAP_FREE( ld->ld_error );
   1008 			ld->ld_error = LDAP_STRDUP( errmsg );
   1009 		}
   1010 		return rc;
   1011 		}
   1012 	case LDAP_OPT_X_TLS_CACERT:
   1013 		if ( lo->ldo_tls_cacert.bv_val )
   1014 			LDAP_FREE( lo->ldo_tls_cacert.bv_val );
   1015 		if ( arg ) {
   1016 			lo->ldo_tls_cacert.bv_len = ((struct berval *)arg)->bv_len;
   1017 			lo->ldo_tls_cacert.bv_val = LDAP_MALLOC( lo->ldo_tls_cacert.bv_len );
   1018 			if ( !lo->ldo_tls_cacert.bv_val )
   1019 				return -1;
   1020 			AC_MEMCPY( lo->ldo_tls_cacert.bv_val, ((struct berval *)arg)->bv_val, lo->ldo_tls_cacert.bv_len );
   1021 		} else {
   1022 			BER_BVZERO( &lo->ldo_tls_cacert );
   1023 		}
   1024 		break;
   1025 	case LDAP_OPT_X_TLS_CERT:
   1026 		if ( lo->ldo_tls_cert.bv_val )
   1027 			LDAP_FREE( lo->ldo_tls_cert.bv_val );
   1028 		if ( arg ) {
   1029 			lo->ldo_tls_cert.bv_len = ((struct berval *)arg)->bv_len;
   1030 			lo->ldo_tls_cert.bv_val = LDAP_MALLOC( lo->ldo_tls_cert.bv_len );
   1031 			if ( !lo->ldo_tls_cert.bv_val )
   1032 				return -1;
   1033 			AC_MEMCPY( lo->ldo_tls_cert.bv_val, ((struct berval *)arg)->bv_val, lo->ldo_tls_cert.bv_len );
   1034 		} else {
   1035 			BER_BVZERO( &lo->ldo_tls_cert );
   1036 		}
   1037 		break;
   1038 	case LDAP_OPT_X_TLS_KEY:
   1039 		if ( lo->ldo_tls_key.bv_val )
   1040 			LDAP_FREE( lo->ldo_tls_key.bv_val );
   1041 		if ( arg ) {
   1042 			lo->ldo_tls_key.bv_len = ((struct berval *)arg)->bv_len;
   1043 			lo->ldo_tls_key.bv_val = LDAP_MALLOC( lo->ldo_tls_key.bv_len );
   1044 			if ( !lo->ldo_tls_key.bv_val )
   1045 				return -1;
   1046 			AC_MEMCPY( lo->ldo_tls_key.bv_val, ((struct berval *)arg)->bv_val, lo->ldo_tls_key.bv_len );
   1047 		} else {
   1048 			BER_BVZERO( &lo->ldo_tls_key );
   1049 		}
   1050 		break;
   1051 	case LDAP_OPT_X_TLS_PEERKEY_HASH: {
   1052 		/* arg = "[hashalg:]pubkey_hash" */
   1053 		struct berval bv;
   1054 		char *p, *pin = arg;
   1055 		int rc = LDAP_SUCCESS;
   1056 
   1057 		if ( !tls_imp->ti_session_pinning ) return -1;
   1058 
   1059 		if ( !pin || !*pin ) {
   1060 			if ( lo->ldo_tls_pin_hashalg ) {
   1061 				LDAP_FREE( lo->ldo_tls_pin_hashalg );
   1062 			} else if ( lo->ldo_tls_pin.bv_val ) {
   1063 				LDAP_FREE( lo->ldo_tls_pin.bv_val );
   1064 			}
   1065 			lo->ldo_tls_pin_hashalg = NULL;
   1066 			BER_BVZERO( &lo->ldo_tls_pin );
   1067 			return rc;
   1068 		}
   1069 
   1070 		pin = LDAP_STRDUP( pin );
   1071 		p = strchr( pin, ':' );
   1072 
   1073 		/* pubkey (its hash) goes in bv, alg in p */
   1074 		if ( p ) {
   1075 			*p = '\0';
   1076 			bv.bv_val = p+1;
   1077 			p = pin;
   1078 		} else {
   1079 			bv.bv_val = pin;
   1080 		}
   1081 
   1082 		bv.bv_len = strlen(bv.bv_val);
   1083 		if ( ldap_int_decode_b64_inplace( &bv ) ) {
   1084 			LDAP_FREE( pin );
   1085 			return -1;
   1086 		}
   1087 
   1088 		if ( ld != NULL ) {
   1089 			LDAPConn *conn = ld->ld_defconn;
   1090 			if ( conn != NULL ) {
   1091 				Sockbuf *sb = conn->lconn_sb;
   1092 				void *sess = ldap_pvt_tls_sb_ctx( sb );
   1093 				if ( sess != NULL ) {
   1094 					rc = tls_imp->ti_session_pinning( ld, sess, p, &bv );
   1095 				}
   1096 			}
   1097 		}
   1098 
   1099 		if ( rc == LDAP_SUCCESS ) {
   1100 			if ( lo->ldo_tls_pin_hashalg ) {
   1101 				LDAP_FREE( lo->ldo_tls_pin_hashalg );
   1102 			} else if ( lo->ldo_tls_pin.bv_val ) {
   1103 				LDAP_FREE( lo->ldo_tls_pin.bv_val );
   1104 			}
   1105 			lo->ldo_tls_pin_hashalg = p;
   1106 			lo->ldo_tls_pin = bv;
   1107 		} else {
   1108 			LDAP_FREE( pin );
   1109 		}
   1110 
   1111 		return rc;
   1112 	}
   1113 	default:
   1114 		return -1;
   1115 	}
   1116 	return 0;
   1117 }
   1118 
   1119 int
   1120 ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
   1121 {
   1122 	Sockbuf *sb;
   1123 	char *host;
   1124 	void *ssl;
   1125 	int ret, async;
   1126 	struct timeval start_time_tv, tv, tv0;
   1127 	ber_socket_t	sd = AC_SOCKET_ERROR;
   1128 
   1129 	if ( !conn )
   1130 		return LDAP_PARAM_ERROR;
   1131 
   1132 	sb = conn->lconn_sb;
   1133 	if( srv ) {
   1134 		host = srv->lud_host;
   1135 	} else {
   1136  		host = conn->lconn_server->lud_host;
   1137 	}
   1138 
   1139 	/* avoid NULL host */
   1140 	if( host == NULL ) {
   1141 		host = "localhost";
   1142 	}
   1143 
   1144 	(void) tls_init( tls_imp, 0 );
   1145 
   1146 	/*
   1147 	 * Use non-blocking io during SSL Handshake when a timeout is configured
   1148 	 */
   1149 	async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC );
   1150 	if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
   1151 		if ( !async ) {
   1152 			/* if async, this has already been set */
   1153 			ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
   1154 		}
   1155 		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
   1156 		tv = ld->ld_options.ldo_tm_net;
   1157 		tv0 = tv;
   1158 #ifdef HAVE_GETTIMEOFDAY
   1159 		gettimeofday( &start_time_tv, NULL );
   1160 #else /* ! HAVE_GETTIMEOFDAY */
   1161 		time( &start_time_tv.tv_sec );
   1162 		start_time_tv.tv_usec = 0;
   1163 #endif /* ! HAVE_GETTIMEOFDAY */
   1164 	}
   1165 
   1166 	ld->ld_errno = LDAP_SUCCESS;
   1167 	ret = ldap_int_tls_connect( ld, conn, host );
   1168 
   1169 	 /* this mainly only happens for non-blocking io
   1170 	  * but can also happen when the handshake is too
   1171 	  * big for a single network message.
   1172 	  */
   1173 	while ( ret > 0 ) {
   1174 		if ( async ) {
   1175 			ld->ld_errno = LDAP_X_CONNECTING;
   1176 			return (ld->ld_errno);
   1177 		} else {
   1178 			struct timeval curr_time_tv, delta_tv;
   1179 			int wr=0;
   1180 
   1181 			if ( sb->sb_trans_needs_read ) {
   1182 				wr=0;
   1183 			} else if ( sb->sb_trans_needs_write ) {
   1184 				wr=1;
   1185 			}
   1186 			Debug1( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ldap_int_tls_connect needs %s\n",
   1187 					wr ? "write": "read" );
   1188 
   1189 			/* This is mostly copied from result.c:wait4msg(), should
   1190 			 * probably be moved into a separate function */
   1191 #ifdef HAVE_GETTIMEOFDAY
   1192 			gettimeofday( &curr_time_tv, NULL );
   1193 #else /* ! HAVE_GETTIMEOFDAY */
   1194 			time( &curr_time_tv.tv_sec );
   1195 			curr_time_tv.tv_usec = 0;
   1196 #endif /* ! HAVE_GETTIMEOFDAY */
   1197 
   1198 			/* delta = curr - start */
   1199 			delta_tv.tv_sec = curr_time_tv.tv_sec - start_time_tv.tv_sec;
   1200 			delta_tv.tv_usec = curr_time_tv.tv_usec - start_time_tv.tv_usec;
   1201 			if ( delta_tv.tv_usec < 0 ) {
   1202 				delta_tv.tv_sec--;
   1203 				delta_tv.tv_usec += 1000000;
   1204 			}
   1205 
   1206 			/* tv0 < delta ? */
   1207 			if ( ( tv0.tv_sec < delta_tv.tv_sec ) ||
   1208 				 ( ( tv0.tv_sec == delta_tv.tv_sec ) &&
   1209 				   ( tv0.tv_usec < delta_tv.tv_usec ) ) )
   1210 			{
   1211 				ret = -1;
   1212 				ld->ld_errno = LDAP_TIMEOUT;
   1213 				break;
   1214 			}
   1215 			/* timeout -= delta_time */
   1216 			tv0.tv_sec -= delta_tv.tv_sec;
   1217 			tv0.tv_usec -= delta_tv.tv_usec;
   1218 			if ( tv0.tv_usec < 0 ) {
   1219 				tv0.tv_sec--;
   1220 				tv0.tv_usec += 1000000;
   1221 			}
   1222 			start_time_tv.tv_sec = curr_time_tv.tv_sec;
   1223 			start_time_tv.tv_usec = curr_time_tv.tv_usec;
   1224 			tv = tv0;
   1225 			Debug3( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ld %p %ld s %ld us to go\n",
   1226 				(void *)ld, (long) tv.tv_sec, (long) tv.tv_usec );
   1227 			ret = ldap_int_poll( ld, sd, &tv, wr);
   1228 			if ( ret < 0 ) {
   1229 				ld->ld_errno = LDAP_TIMEOUT;
   1230 				break;
   1231 			}
   1232 		}
   1233 		ret = ldap_int_tls_connect( ld, conn, host );
   1234 	}
   1235 
   1236 	if ( !async && ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
   1237 		/* Restore original sb status */
   1238 		ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)0 );
   1239 	}
   1240 
   1241 	if ( ret < 0 ) {
   1242 		if ( ld->ld_errno == LDAP_SUCCESS )
   1243 			ld->ld_errno = LDAP_CONNECT_ERROR;
   1244 		return (ld->ld_errno);
   1245 	}
   1246 
   1247 	return LDAP_SUCCESS;
   1248 }
   1249 
   1250 void *
   1251 ldap_pvt_tls_sb_ctx( Sockbuf *sb )
   1252 {
   1253 	void			*p = NULL;
   1254 
   1255 	ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p );
   1256 	return p;
   1257 }
   1258 
   1259 int
   1260 ldap_pvt_tls_get_strength( void *s )
   1261 {
   1262 	tls_session *session = s;
   1263 
   1264 	return tls_imp->ti_session_strength( session );
   1265 }
   1266 
   1267 int
   1268 ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func, unsigned flags )
   1269 {
   1270 	tls_session *session = s;
   1271 	struct berval der_dn;
   1272 	int rc;
   1273 
   1274 	rc = tls_imp->ti_session_my_dn( session, &der_dn );
   1275 	if ( rc == LDAP_SUCCESS )
   1276 		rc = ldap_X509dn2bv(&der_dn, dn, (LDAPDN_rewrite_func *)func, flags );
   1277 	return rc;
   1278 }
   1279 
   1280 int
   1281 ldap_pvt_tls_get_unique( void *s, struct berval *buf, int is_server )
   1282 {
   1283 	tls_session *session = s;
   1284 	return tls_imp->ti_session_unique( session, buf, is_server );
   1285 }
   1286 
   1287 int
   1288 ldap_pvt_tls_get_endpoint( void *s, struct berval *buf, int is_server )
   1289 {
   1290 	tls_session *session = s;
   1291 	return tls_imp->ti_session_endpoint( session, buf, is_server );
   1292 }
   1293 
   1294 const char *
   1295 ldap_pvt_tls_get_version( void *s )
   1296 {
   1297 	tls_session *session = s;
   1298 	return tls_imp->ti_session_version( session );
   1299 }
   1300 
   1301 const char *
   1302 ldap_pvt_tls_get_cipher( void *s )
   1303 {
   1304 	tls_session *session = s;
   1305 	return tls_imp->ti_session_cipher( session );
   1306 }
   1307 
   1308 int
   1309 ldap_pvt_tls_get_peercert( void *s, struct berval *der )
   1310 {
   1311 	tls_session *session = s;
   1312 	return tls_imp->ti_session_peercert( session, der );
   1313 }
   1314 #endif /* HAVE_TLS */
   1315 
   1316 int
   1317 ldap_start_tls( LDAP *ld,
   1318 	LDAPControl **serverctrls,
   1319 	LDAPControl **clientctrls,
   1320 	int *msgidp )
   1321 {
   1322 	return ldap_extended_operation( ld, LDAP_EXOP_START_TLS,
   1323 		NULL, serverctrls, clientctrls, msgidp );
   1324 }
   1325 
   1326 int
   1327 ldap_install_tls( LDAP *ld )
   1328 {
   1329 #ifndef HAVE_TLS
   1330 	return LDAP_NOT_SUPPORTED;
   1331 #else
   1332 	if ( ldap_tls_inplace( ld ) ) {
   1333 		return LDAP_LOCAL_ERROR;
   1334 	}
   1335 
   1336 	return ldap_int_tls_start( ld, ld->ld_defconn, NULL );
   1337 #endif
   1338 }
   1339 
   1340 int
   1341 ldap_start_tls_s ( LDAP *ld,
   1342 	LDAPControl **serverctrls,
   1343 	LDAPControl **clientctrls )
   1344 {
   1345 #ifndef HAVE_TLS
   1346 	return LDAP_NOT_SUPPORTED;
   1347 #else
   1348 	int rc;
   1349 	char *rspoid = NULL;
   1350 	struct berval *rspdata = NULL;
   1351 
   1352 	/* XXYYZ: this initiates operation only on default connection! */
   1353 
   1354 	if ( ldap_tls_inplace( ld ) ) {
   1355 		return LDAP_LOCAL_ERROR;
   1356 	}
   1357 
   1358 	rc = ldap_extended_operation_s( ld, LDAP_EXOP_START_TLS,
   1359 		NULL, serverctrls, clientctrls, &rspoid, &rspdata );
   1360 
   1361 	if ( rspoid != NULL ) {
   1362 		LDAP_FREE(rspoid);
   1363 	}
   1364 
   1365 	if ( rspdata != NULL ) {
   1366 		ber_bvfree( rspdata );
   1367 	}
   1368 
   1369 	if ( rc == LDAP_SUCCESS ) {
   1370 		rc = ldap_int_tls_start( ld, ld->ld_defconn, NULL );
   1371 	}
   1372 
   1373 	return rc;
   1374 #endif
   1375 }
   1376 
   1377 /* These tags probably all belong in lber.h, but they're
   1378  * not normally encountered when processing LDAP, so maybe
   1379  * they belong somewhere else instead.
   1380  */
   1381 
   1382 #define LBER_TAG_OID		((ber_tag_t) 0x06UL)
   1383 
   1384 /* Tags for string types used in a DirectoryString.
   1385  *
   1386  * Note that IA5string is not one of the defined choices for
   1387  * DirectoryString in X.520, but it gets used for email AVAs.
   1388  */
   1389 #define	LBER_TAG_UTF8		((ber_tag_t) 0x0cUL)
   1390 #define	LBER_TAG_PRINTABLE	((ber_tag_t) 0x13UL)
   1391 #define	LBER_TAG_TELETEX	((ber_tag_t) 0x14UL)
   1392 #define	LBER_TAG_IA5		((ber_tag_t) 0x16UL)
   1393 #define	LBER_TAG_UNIVERSAL	((ber_tag_t) 0x1cUL)
   1394 #define	LBER_TAG_BMP		((ber_tag_t) 0x1eUL)
   1395 
   1396 static oid_name *
   1397 find_oid( struct berval *oid )
   1398 {
   1399 	int i;
   1400 
   1401 	for ( i=0; !BER_BVISNULL( &oids[i].oid ); i++ ) {
   1402 		if ( oids[i].oid.bv_len != oid->bv_len ) continue;
   1403 		if ( !strcmp( oids[i].oid.bv_val, oid->bv_val ))
   1404 			return &oids[i];
   1405 	}
   1406 	return NULL;
   1407 }
   1408 
   1409 /* Converts BER Bitstring value to LDAP BitString value (RFC4517)
   1410  *
   1411  * berValue    : IN
   1412  * rfc4517Value: OUT
   1413  *
   1414  * berValue and ldapValue should not be NULL
   1415  */
   1416 
   1417 #define BITS_PER_BYTE	8
   1418 #define SQUOTE_LENGTH	1
   1419 #define B_CHAR_LENGTH	1
   1420 #define STR_OVERHEAD    (2*SQUOTE_LENGTH + B_CHAR_LENGTH)
   1421 
   1422 static int
   1423 der_to_ldap_BitString (struct berval *berValue,
   1424                                    struct berval *ldapValue)
   1425 {
   1426 	ber_len_t bitPadding=0;
   1427 	ber_len_t bits, maxBits;
   1428 	char *tmpStr;
   1429 	unsigned char byte;
   1430 	ber_len_t bitLength;
   1431 	ber_len_t valLen;
   1432 	unsigned char* valPtr;
   1433 
   1434 	ldapValue->bv_len=0;
   1435 	ldapValue->bv_val=NULL;
   1436 
   1437 	/* Gets padding and points to binary data */
   1438 	valLen=berValue->bv_len;
   1439 	valPtr=(unsigned char*)berValue->bv_val;
   1440 	if (valLen) {
   1441 		bitPadding=(ber_len_t)(valPtr[0]);
   1442 		valLen--;
   1443 		valPtr++;
   1444 	}
   1445 	/* If Block is non DER encoding fixes to DER encoding */
   1446 	if (bitPadding >= BITS_PER_BYTE) {
   1447 		if (valLen*BITS_PER_BYTE > bitPadding ) {
   1448 			valLen-=(bitPadding/BITS_PER_BYTE);
   1449 			bitPadding%=BITS_PER_BYTE;
   1450 		} else {
   1451 			valLen=0;
   1452 			bitPadding=0;
   1453 		}
   1454 	}
   1455 	/* Just in case bad encoding */
   1456 	if (valLen*BITS_PER_BYTE < bitPadding ) {
   1457 		bitPadding=0;
   1458 		valLen=0;
   1459 	}
   1460 
   1461 	/* Gets buffer to hold RFC4517 Bit String format */
   1462 	bitLength=valLen*BITS_PER_BYTE-bitPadding;
   1463 	tmpStr=LDAP_MALLOC(bitLength + STR_OVERHEAD + 1);
   1464 
   1465 	if (!tmpStr)
   1466 		return LDAP_NO_MEMORY;
   1467 
   1468 	ldapValue->bv_val=tmpStr;
   1469 	ldapValue->bv_len=bitLength + STR_OVERHEAD;
   1470 
   1471 	/* Formatting in '*binary-digit'B format */
   1472 	maxBits=BITS_PER_BYTE;
   1473 	*tmpStr++ ='\'';
   1474 	while(valLen) {
   1475 		byte=*valPtr;
   1476 		if (valLen==1)
   1477 			maxBits-=bitPadding;
   1478 		for (bits=0; bits<maxBits; bits++) {
   1479 			if (0x80 & byte)
   1480 				*tmpStr='1';
   1481 			else
   1482 				*tmpStr='0';
   1483 			tmpStr++;
   1484 			byte<<=1;
   1485 		}
   1486 		valPtr++;
   1487 		valLen--;
   1488 	}
   1489 	*tmpStr++ ='\'';
   1490 	*tmpStr++ ='B';
   1491 	*tmpStr=0;
   1492 
   1493 	return LDAP_SUCCESS;
   1494 }
   1495 
   1496 /* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
   1497  * x509_name must be raw DER. If func is non-NULL, the
   1498  * constructed DN will use numeric OIDs to identify attributeTypes,
   1499  * and the func() will be invoked to rewrite the DN with the given
   1500  * flags.
   1501  *
   1502  * Otherwise the DN will use shortNames from a hardcoded table.
   1503  */
   1504 int
   1505 ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
   1506 	unsigned flags )
   1507 {
   1508 	LDAPDN	newDN;
   1509 	LDAPRDN	newRDN;
   1510 	LDAPAVA *newAVA, *baseAVA;
   1511 	BerElementBuffer berbuf;
   1512 	BerElement *ber = (BerElement *)&berbuf;
   1513 	char oids[8192], *oidptr = oids, *oidbuf = NULL;
   1514 	void *ptrs[2048];
   1515 	char *dn_end, *rdn_end;
   1516 	int i, navas, nrdns, rc = LDAP_SUCCESS;
   1517 	size_t dnsize, oidrem = sizeof(oids), oidsize = 0;
   1518 	int csize;
   1519 	ber_tag_t tag;
   1520 	ber_len_t len;
   1521 	oid_name *oidname;
   1522 
   1523 	struct berval	Oid, Val, oid2, *in = x509_name;
   1524 
   1525 	assert( bv != NULL );
   1526 
   1527 	bv->bv_len = 0;
   1528 	bv->bv_val = NULL;
   1529 
   1530 	navas = 0;
   1531 	nrdns = 0;
   1532 
   1533 	/* A DN is a SEQUENCE of RDNs. An RDN is a SET of AVAs.
   1534 	 * An AVA is a SEQUENCE of attr and value.
   1535 	 * Count the number of AVAs and RDNs
   1536 	 */
   1537 	ber_init2( ber, in, LBER_USE_DER );
   1538 	tag = ber_peek_tag( ber, &len );
   1539 	if ( tag != LBER_SEQUENCE )
   1540 		return LDAP_DECODING_ERROR;
   1541 
   1542 	for ( tag = ber_first_element( ber, &len, &dn_end );
   1543 		tag == LBER_SET;
   1544 		tag = ber_next_element( ber, &len, dn_end )) {
   1545 		nrdns++;
   1546 		for ( tag = ber_first_element( ber, &len, &rdn_end );
   1547 			tag == LBER_SEQUENCE;
   1548 			tag = ber_next_element( ber, &len, rdn_end )) {
   1549 			if ( rdn_end > dn_end )
   1550 				return LDAP_DECODING_ERROR;
   1551 			tag = ber_skip_tag( ber, &len );
   1552 			ber_skip_data( ber, len );
   1553 			navas++;
   1554 		}
   1555 	}
   1556 
   1557 	/* Rewind and prepare to extract */
   1558 	ber_rewind( ber );
   1559 	tag = ber_first_element( ber, &len, &dn_end );
   1560 	if ( tag != LBER_SET )
   1561 		return LDAP_DECODING_ERROR;
   1562 
   1563 	/* Allocate the DN/RDN/AVA stuff as a single block */
   1564 	dnsize = sizeof(LDAPRDN) * (nrdns+1);
   1565 	dnsize += sizeof(LDAPAVA *) * (navas+nrdns);
   1566 	dnsize += sizeof(LDAPAVA) * navas;
   1567 	if (dnsize > sizeof(ptrs)) {
   1568 		newDN = (LDAPDN)LDAP_MALLOC( dnsize );
   1569 		if ( newDN == NULL )
   1570 			return LDAP_NO_MEMORY;
   1571 	} else {
   1572 		newDN = (LDAPDN)(char *)ptrs;
   1573 	}
   1574 
   1575 	newDN[nrdns] = NULL;
   1576 	newRDN = (LDAPRDN)(newDN + nrdns+1);
   1577 	newAVA = (LDAPAVA *)(newRDN + navas + nrdns);
   1578 	baseAVA = newAVA;
   1579 
   1580 	for ( i = nrdns - 1; i >= 0; i-- ) {
   1581 		newDN[i] = newRDN;
   1582 
   1583 		for ( tag = ber_first_element( ber, &len, &rdn_end );
   1584 			tag == LBER_SEQUENCE;
   1585 			tag = ber_next_element( ber, &len, rdn_end )) {
   1586 
   1587 			*newRDN++ = newAVA;
   1588 			tag = ber_skip_tag( ber, &len );
   1589 			tag = ber_get_stringbv( ber, &Oid, LBER_BV_NOTERM );
   1590 			if ( tag != LBER_TAG_OID ) {
   1591 				rc = LDAP_DECODING_ERROR;
   1592 				goto nomem;
   1593 			}
   1594 
   1595 			oid2.bv_val = oidptr;
   1596 			oid2.bv_len = oidrem;
   1597 			if ( ber_decode_oid( &Oid, &oid2 ) < 0 ) {
   1598 				rc = LDAP_DECODING_ERROR;
   1599 				goto nomem;
   1600 			}
   1601 			oidname = find_oid( &oid2 );
   1602 			if ( !oidname ) {
   1603 				newAVA->la_attr = oid2;
   1604 				oidptr += oid2.bv_len + 1;
   1605 				oidrem -= oid2.bv_len + 1;
   1606 
   1607 				/* Running out of OID buffer space? */
   1608 				if (oidrem < 128) {
   1609 					if ( oidsize == 0 ) {
   1610 						oidsize = sizeof(oids) * 2;
   1611 						oidrem = oidsize;
   1612 						oidbuf = LDAP_MALLOC( oidsize );
   1613 						if ( oidbuf == NULL ) goto nomem;
   1614 						oidptr = oidbuf;
   1615 					} else {
   1616 						char *old = oidbuf;
   1617 						oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 );
   1618 						if ( oidbuf == NULL ) goto nomem;
   1619 						/* Buffer moved! Fix AVA pointers */
   1620 						if ( old != oidbuf ) {
   1621 							LDAPAVA *a;
   1622 							long dif = oidbuf - old;
   1623 
   1624 							for (a=baseAVA; a<=newAVA; a++){
   1625 								if (a->la_attr.bv_val >= old &&
   1626 									a->la_attr.bv_val <= (old + oidsize))
   1627 									a->la_attr.bv_val += dif;
   1628 							}
   1629 						}
   1630 						oidptr = oidbuf + oidsize - oidrem;
   1631 						oidrem += oidsize;
   1632 						oidsize *= 2;
   1633 					}
   1634 				}
   1635 			} else {
   1636 				if ( func ) {
   1637 					newAVA->la_attr = oidname->oid;
   1638 				} else {
   1639 					newAVA->la_attr = oidname->name;
   1640 				}
   1641 			}
   1642 			newAVA->la_private = NULL;
   1643 			newAVA->la_flags = LDAP_AVA_STRING;
   1644 			tag = ber_get_stringbv( ber, &Val, LBER_BV_NOTERM );
   1645 			switch(tag) {
   1646 			case LBER_TAG_UNIVERSAL:
   1647 				/* This uses 32-bit ISO 10646-1 */
   1648 				csize = 4; goto to_utf8;
   1649 			case LBER_TAG_BMP:
   1650 				/* This uses 16-bit ISO 10646-1 */
   1651 				csize = 2; goto to_utf8;
   1652 			case LBER_TAG_TELETEX:
   1653 				/* This uses 8-bit, assume ISO 8859-1 */
   1654 				csize = 1;
   1655 to_utf8:		rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value );
   1656 				newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
   1657 allocd:
   1658 				newAVA->la_flags |= LDAP_AVA_FREE_VALUE;
   1659 				if (rc != LDAP_SUCCESS) goto nomem;
   1660 				break;
   1661 			case LBER_TAG_UTF8:
   1662 				newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
   1663 				/* This is already in UTF-8 encoding */
   1664 			case LBER_TAG_IA5:
   1665 			case LBER_TAG_PRINTABLE:
   1666 				/* These are always 7-bit strings */
   1667 				newAVA->la_value = Val;
   1668 				break;
   1669 			case LBER_BITSTRING:
   1670 				/* X.690 bitString value converted to RFC4517 Bit String */
   1671 				rc = der_to_ldap_BitString( &Val, &newAVA->la_value );
   1672 				goto allocd;
   1673 			case LBER_DEFAULT:
   1674 				/* decode error */
   1675 				rc = LDAP_DECODING_ERROR;
   1676 				goto nomem;
   1677 			default:
   1678 				/* Not a string type at all */
   1679 				newAVA->la_flags = 0;
   1680 				newAVA->la_value = Val;
   1681 				break;
   1682 			}
   1683 			newAVA++;
   1684 		}
   1685 		*newRDN++ = NULL;
   1686 		tag = ber_next_element( ber, &len, dn_end );
   1687 	}
   1688 
   1689 	if ( func ) {
   1690 		rc = func( newDN, flags, NULL );
   1691 		if ( rc != LDAP_SUCCESS )
   1692 			goto nomem;
   1693 	}
   1694 
   1695 	rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL );
   1696 
   1697 nomem:
   1698 	for (;baseAVA < newAVA; baseAVA++) {
   1699 		if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR)
   1700 			LDAP_FREE( baseAVA->la_attr.bv_val );
   1701 		if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE)
   1702 			LDAP_FREE( baseAVA->la_value.bv_val );
   1703 	}
   1704 
   1705 	if ( oidsize != 0 )
   1706 		LDAP_FREE( oidbuf );
   1707 	if ( newDN != (LDAPDN)(char *) ptrs )
   1708 		LDAP_FREE( newDN );
   1709 	return rc;
   1710 }
   1711 
   1712