1 /* $NetBSD: tls2.c,v 1.2 2020/08/11 13:15:38 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-2020 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.2 2020/08/11 13:15:38 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 #ifdef LDAP_DEVEL 52 #define LDAP_USE_NON_BLOCKING_TLS 53 #endif /* LDAP_DEVEL */ 54 55 /* RFC2459 minimum required set of supported attribute types 56 * in a certificate DN 57 */ 58 typedef struct oid_name { 59 struct berval oid; 60 struct berval name; 61 } oid_name; 62 63 static oid_name oids[] = { 64 { BER_BVC("2.5.4.3"), BER_BVC("cn") }, 65 { BER_BVC("2.5.4.4"), BER_BVC("sn") }, 66 { BER_BVC("2.5.4.6"), BER_BVC("c") }, 67 { BER_BVC("2.5.4.7"), BER_BVC("l") }, 68 { BER_BVC("2.5.4.8"), BER_BVC("st") }, 69 { BER_BVC("2.5.4.10"), BER_BVC("o") }, 70 { BER_BVC("2.5.4.11"), BER_BVC("ou") }, 71 { BER_BVC("2.5.4.12"), BER_BVC("title") }, 72 { BER_BVC("2.5.4.41"), BER_BVC("name") }, 73 { BER_BVC("2.5.4.42"), BER_BVC("givenName") }, 74 { BER_BVC("2.5.4.43"), BER_BVC("initials") }, 75 { BER_BVC("2.5.4.44"), BER_BVC("generationQualifier") }, 76 { BER_BVC("2.5.4.46"), BER_BVC("dnQualifier") }, 77 { BER_BVC("1.2.840.113549.1.9.1"), BER_BVC("email") }, 78 { BER_BVC("0.9.2342.19200300.100.1.25"), BER_BVC("dc") }, 79 { BER_BVNULL, BER_BVNULL } 80 }; 81 82 #ifdef HAVE_TLS 83 84 void 85 ldap_pvt_tls_ctx_free ( void *c ) 86 { 87 if ( !c ) return; 88 tls_imp->ti_ctx_free( c ); 89 } 90 91 static void 92 tls_ctx_ref( tls_ctx *ctx ) 93 { 94 if ( !ctx ) return; 95 96 tls_imp->ti_ctx_ref( ctx ); 97 } 98 99 #ifdef LDAP_R_COMPILE 100 /* 101 * an extra mutex for the default ctx. 102 */ 103 static ldap_pvt_thread_mutex_t tls_def_ctx_mutex; 104 #endif 105 106 void 107 ldap_int_tls_destroy( struct ldapoptions *lo ) 108 { 109 if ( lo->ldo_tls_ctx ) { 110 ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx ); 111 lo->ldo_tls_ctx = NULL; 112 } 113 114 if ( lo->ldo_tls_certfile ) { 115 LDAP_FREE( lo->ldo_tls_certfile ); 116 lo->ldo_tls_certfile = NULL; 117 } 118 if ( lo->ldo_tls_keyfile ) { 119 LDAP_FREE( lo->ldo_tls_keyfile ); 120 lo->ldo_tls_keyfile = NULL; 121 } 122 if ( lo->ldo_tls_dhfile ) { 123 LDAP_FREE( lo->ldo_tls_dhfile ); 124 lo->ldo_tls_dhfile = NULL; 125 } 126 if ( lo->ldo_tls_ecname ) { 127 LDAP_FREE( lo->ldo_tls_ecname ); 128 lo->ldo_tls_ecname = NULL; 129 } 130 if ( lo->ldo_tls_cacertfile ) { 131 LDAP_FREE( lo->ldo_tls_cacertfile ); 132 lo->ldo_tls_cacertfile = NULL; 133 } 134 if ( lo->ldo_tls_cacertdir ) { 135 LDAP_FREE( lo->ldo_tls_cacertdir ); 136 lo->ldo_tls_cacertdir = NULL; 137 } 138 if ( lo->ldo_tls_ciphersuite ) { 139 LDAP_FREE( lo->ldo_tls_ciphersuite ); 140 lo->ldo_tls_ciphersuite = NULL; 141 } 142 if ( lo->ldo_tls_crlfile ) { 143 LDAP_FREE( lo->ldo_tls_crlfile ); 144 lo->ldo_tls_crlfile = NULL; 145 } 146 } 147 148 /* 149 * Tear down the TLS subsystem. Should only be called once. 150 */ 151 void 152 ldap_pvt_tls_destroy( void ) 153 { 154 struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT(); 155 156 ldap_int_tls_destroy( lo ); 157 158 tls_imp->ti_tls_destroy(); 159 } 160 161 /* 162 * Initialize a particular TLS implementation. 163 * Called once per implementation. 164 */ 165 static int 166 tls_init(tls_impl *impl ) 167 { 168 static int tls_initialized = 0; 169 170 if ( !tls_initialized++ ) { 171 #ifdef LDAP_R_COMPILE 172 ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex ); 173 #endif 174 } 175 176 if ( impl->ti_inited++ ) return 0; 177 178 #ifdef LDAP_R_COMPILE 179 impl->ti_thr_init(); 180 #endif 181 return impl->ti_tls_init(); 182 } 183 184 /* 185 * Initialize TLS subsystem. Called once per implementation. 186 */ 187 int 188 ldap_pvt_tls_init( void ) 189 { 190 return tls_init( tls_imp ); 191 } 192 193 /* 194 * initialize a new TLS context 195 */ 196 static int 197 ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server ) 198 { 199 int rc = 0; 200 tls_impl *ti = tls_imp; 201 struct ldaptls lts = lo->ldo_tls_info; 202 203 if ( lo->ldo_tls_ctx ) 204 return 0; 205 206 tls_init( ti ); 207 208 if ( is_server && !lts.lt_certfile && !lts.lt_keyfile && 209 !lts.lt_cacertfile && !lts.lt_cacertdir ) { 210 /* minimum configuration not provided */ 211 return LDAP_NOT_SUPPORTED; 212 } 213 214 #ifdef HAVE_EBCDIC 215 /* This ASCII/EBCDIC handling is a real pain! */ 216 if ( lts.lt_ciphersuite ) { 217 lts.lt_ciphersuite = LDAP_STRDUP( lts.lt_ciphersuite ); 218 __atoe( lts.lt_ciphersuite ); 219 } 220 if ( lts.lt_cacertfile ) { 221 lts.lt_cacertfile = LDAP_STRDUP( lts.lt_cacertfile ); 222 __atoe( lts.lt_cacertfile ); 223 } 224 if ( lts.lt_certfile ) { 225 lts.lt_certfile = LDAP_STRDUP( lts.lt_certfile ); 226 __atoe( lts.lt_certfile ); 227 } 228 if ( lts.lt_keyfile ) { 229 lts.lt_keyfile = LDAP_STRDUP( lts.lt_keyfile ); 230 __atoe( lts.lt_keyfile ); 231 } 232 if ( lts.lt_crlfile ) { 233 lts.lt_crlfile = LDAP_STRDUP( lts.lt_crlfile ); 234 __atoe( lts.lt_crlfile ); 235 } 236 if ( lts.lt_cacertdir ) { 237 lts.lt_cacertdir = LDAP_STRDUP( lts.lt_cacertdir ); 238 __atoe( lts.lt_cacertdir ); 239 } 240 if ( lts.lt_dhfile ) { 241 lts.lt_dhfile = LDAP_STRDUP( lts.lt_dhfile ); 242 __atoe( lts.lt_dhfile ); 243 } 244 if ( lts.lt_ecname ) { 245 lts.lt_ecname = LDAP_STRDUP( lts.lt_ecname ); 246 __atoe( lts.lt_ecname ); 247 } 248 #endif 249 lo->ldo_tls_ctx = ti->ti_ctx_new( lo ); 250 if ( lo->ldo_tls_ctx == NULL ) { 251 Debug( LDAP_DEBUG_ANY, 252 "TLS: could not allocate default ctx.\n", 253 0,0,0); 254 rc = -1; 255 goto error_exit; 256 } 257 258 rc = ti->ti_ctx_init( lo, <s, is_server ); 259 260 error_exit: 261 if ( rc < 0 && lo->ldo_tls_ctx != NULL ) { 262 ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx ); 263 lo->ldo_tls_ctx = NULL; 264 } 265 #ifdef HAVE_EBCDIC 266 LDAP_FREE( lts.lt_ciphersuite ); 267 LDAP_FREE( lts.lt_cacertfile ); 268 LDAP_FREE( lts.lt_certfile ); 269 LDAP_FREE( lts.lt_keyfile ); 270 LDAP_FREE( lts.lt_crlfile ); 271 LDAP_FREE( lts.lt_cacertdir ); 272 LDAP_FREE( lts.lt_dhfile ); 273 LDAP_FREE( lts.lt_ecname ); 274 #endif 275 return rc; 276 } 277 278 /* 279 * initialize the default context 280 */ 281 int 282 ldap_pvt_tls_init_def_ctx( int is_server ) 283 { 284 struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT(); 285 int rc; 286 LDAP_MUTEX_LOCK( &tls_def_ctx_mutex ); 287 rc = ldap_int_tls_init_ctx( lo, is_server ); 288 LDAP_MUTEX_UNLOCK( &tls_def_ctx_mutex ); 289 return rc; 290 } 291 292 static tls_session * 293 alloc_handle( void *ctx_arg, int is_server ) 294 { 295 tls_ctx *ctx; 296 tls_session *ssl; 297 298 if ( ctx_arg ) { 299 ctx = ctx_arg; 300 } else { 301 struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT(); 302 if ( ldap_pvt_tls_init_def_ctx( is_server ) < 0 ) return NULL; 303 ctx = lo->ldo_tls_ctx; 304 } 305 306 ssl = tls_imp->ti_session_new( ctx, is_server ); 307 if ( ssl == NULL ) { 308 Debug( LDAP_DEBUG_ANY,"TLS: can't create ssl handle.\n",0,0,0); 309 return NULL; 310 } 311 return ssl; 312 } 313 314 static int 315 update_flags( Sockbuf *sb, tls_session * ssl, int rc ) 316 { 317 sb->sb_trans_needs_read = 0; 318 sb->sb_trans_needs_write = 0; 319 320 return tls_imp->ti_session_upflags( sb, ssl, rc ); 321 } 322 323 /* 324 * Call this to do a TLS connect on a sockbuf. ctx_arg can be 325 * a SSL_CTX * or NULL, in which case the default ctx is used. 326 * 327 * Return value: 328 * 329 * 0 - Success. Connection is ready for communication. 330 * <0 - Error. Can't create a TLS stream. 331 * >0 - Partial success. 332 * Do a select (using information from lber_pvt_sb_needs_{read,write} 333 * and call again. 334 */ 335 336 static int 337 ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host ) 338 { 339 Sockbuf *sb = conn->lconn_sb; 340 int err; 341 tls_session *ssl = NULL; 342 343 if ( HAS_TLS( sb )) { 344 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl ); 345 } else { 346 struct ldapoptions *lo; 347 tls_ctx *ctx; 348 349 ctx = ld->ld_options.ldo_tls_ctx; 350 351 ssl = alloc_handle( ctx, 0 ); 352 353 if ( ssl == NULL ) return -1; 354 355 #ifdef LDAP_DEBUG 356 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, 357 LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" ); 358 #endif 359 ber_sockbuf_add_io( sb, tls_imp->ti_sbio, 360 LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl ); 361 362 lo = LDAP_INT_GLOBAL_OPT(); 363 if( ctx == NULL ) { 364 ctx = lo->ldo_tls_ctx; 365 ld->ld_options.ldo_tls_ctx = ctx; 366 tls_ctx_ref( ctx ); 367 } 368 if ( ld->ld_options.ldo_tls_connect_cb ) 369 ld->ld_options.ldo_tls_connect_cb( ld, ssl, ctx, 370 ld->ld_options.ldo_tls_connect_arg ); 371 if ( lo && lo->ldo_tls_connect_cb && lo->ldo_tls_connect_cb != 372 ld->ld_options.ldo_tls_connect_cb ) 373 lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg ); 374 } 375 376 err = tls_imp->ti_session_connect( ld, ssl ); 377 378 #ifdef HAVE_WINSOCK 379 errno = WSAGetLastError(); 380 #endif 381 382 if ( err == 0 ) { 383 err = ldap_pvt_tls_check_hostname( ld, ssl, host ); 384 } 385 386 if ( err < 0 ) 387 { 388 char buf[256], *msg; 389 if ( update_flags( sb, ssl, err )) { 390 return 1; 391 } 392 393 msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) ); 394 if ( msg ) { 395 if ( ld->ld_error ) { 396 LDAP_FREE( ld->ld_error ); 397 } 398 ld->ld_error = LDAP_STRDUP( msg ); 399 #ifdef HAVE_EBCDIC 400 if ( ld->ld_error ) __etoa(ld->ld_error); 401 #endif 402 } 403 404 Debug( LDAP_DEBUG_ANY,"TLS: can't connect: %s.\n", 405 ld->ld_error ? ld->ld_error : "" ,0,0); 406 407 ber_sockbuf_remove_io( sb, tls_imp->ti_sbio, 408 LBER_SBIOD_LEVEL_TRANSPORT ); 409 #ifdef LDAP_DEBUG 410 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug, 411 LBER_SBIOD_LEVEL_TRANSPORT ); 412 #endif 413 return -1; 414 } 415 416 return 0; 417 } 418 419 /* 420 * Call this to do a TLS accept on a sockbuf. 421 * Everything else is the same as with tls_connect. 422 */ 423 int 424 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg ) 425 { 426 int err; 427 tls_session *ssl = NULL; 428 429 if ( HAS_TLS( sb )) { 430 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl ); 431 } else { 432 ssl = alloc_handle( ctx_arg, 1 ); 433 if ( ssl == NULL ) return -1; 434 435 #ifdef LDAP_DEBUG 436 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, 437 LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" ); 438 #endif 439 ber_sockbuf_add_io( sb, tls_imp->ti_sbio, 440 LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl ); 441 } 442 443 err = tls_imp->ti_session_accept( ssl ); 444 445 #ifdef HAVE_WINSOCK 446 errno = WSAGetLastError(); 447 #endif 448 449 if ( err < 0 ) 450 { 451 if ( update_flags( sb, ssl, err )) return 1; 452 453 if ( DebugTest( LDAP_DEBUG_ANY ) ) { 454 char buf[256], *msg; 455 msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) ); 456 Debug( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n", 457 msg ? msg : "(unknown)", 0, 0 ); 458 } 459 460 ber_sockbuf_remove_io( sb, tls_imp->ti_sbio, 461 LBER_SBIOD_LEVEL_TRANSPORT ); 462 #ifdef LDAP_DEBUG 463 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug, 464 LBER_SBIOD_LEVEL_TRANSPORT ); 465 #endif 466 return -1; 467 } 468 return 0; 469 } 470 471 int 472 ldap_pvt_tls_inplace ( Sockbuf *sb ) 473 { 474 return HAS_TLS( sb ) ? 1 : 0; 475 } 476 477 int 478 ldap_tls_inplace( LDAP *ld ) 479 { 480 Sockbuf *sb = NULL; 481 482 if ( ld->ld_defconn && ld->ld_defconn->lconn_sb ) { 483 sb = ld->ld_defconn->lconn_sb; 484 485 } else if ( ld->ld_sb ) { 486 sb = ld->ld_sb; 487 488 } else { 489 return 0; 490 } 491 492 return ldap_pvt_tls_inplace( sb ); 493 } 494 495 int 496 ldap_pvt_tls_get_peer_dn( void *s, struct berval *dn, 497 LDAPDN_rewrite_dummy *func, unsigned flags ) 498 { 499 tls_session *session = s; 500 struct berval bvdn; 501 int rc; 502 503 rc = tls_imp->ti_session_peer_dn( session, &bvdn ); 504 if ( rc ) return rc; 505 506 rc = ldap_X509dn2bv( &bvdn, dn, 507 (LDAPDN_rewrite_func *)func, flags); 508 return rc; 509 } 510 511 int 512 ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in ) 513 { 514 tls_session *session = s; 515 516 if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER && 517 ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) { 518 ld->ld_errno = tls_imp->ti_session_chkhost( ld, session, name_in ); 519 if (ld->ld_errno != LDAP_SUCCESS) { 520 return ld->ld_errno; 521 } 522 } 523 524 return LDAP_SUCCESS; 525 } 526 527 int 528 ldap_int_tls_config( LDAP *ld, int option, const char *arg ) 529 { 530 int i; 531 532 switch( option ) { 533 case LDAP_OPT_X_TLS_CACERTFILE: 534 case LDAP_OPT_X_TLS_CACERTDIR: 535 case LDAP_OPT_X_TLS_CERTFILE: 536 case LDAP_OPT_X_TLS_KEYFILE: 537 case LDAP_OPT_X_TLS_RANDOM_FILE: 538 case LDAP_OPT_X_TLS_CIPHER_SUITE: 539 case LDAP_OPT_X_TLS_DHFILE: 540 case LDAP_OPT_X_TLS_CRLFILE: /* GnuTLS only */ 541 return ldap_pvt_tls_set_option( ld, option, (void *) arg ); 542 543 case LDAP_OPT_X_TLS_REQUIRE_CERT: 544 case LDAP_OPT_X_TLS: 545 i = -1; 546 if ( strcasecmp( arg, "never" ) == 0 ) { 547 i = LDAP_OPT_X_TLS_NEVER ; 548 549 } else if ( strcasecmp( arg, "demand" ) == 0 ) { 550 i = LDAP_OPT_X_TLS_DEMAND ; 551 552 } else if ( strcasecmp( arg, "allow" ) == 0 ) { 553 i = LDAP_OPT_X_TLS_ALLOW ; 554 555 } else if ( strcasecmp( arg, "try" ) == 0 ) { 556 i = LDAP_OPT_X_TLS_TRY ; 557 558 } else if ( ( strcasecmp( arg, "hard" ) == 0 ) || 559 ( strcasecmp( arg, "on" ) == 0 ) || 560 ( strcasecmp( arg, "yes" ) == 0) || 561 ( strcasecmp( arg, "true" ) == 0 ) ) 562 { 563 i = LDAP_OPT_X_TLS_HARD ; 564 } 565 566 if (i >= 0) { 567 return ldap_pvt_tls_set_option( ld, option, &i ); 568 } 569 return -1; 570 case LDAP_OPT_X_TLS_PROTOCOL_MIN: { 571 char *next; 572 long l; 573 l = strtol( arg, &next, 10 ); 574 if ( l < 0 || l > 0xff || next == arg || 575 ( *next != '\0' && *next != '.' ) ) 576 return -1; 577 i = l << 8; 578 if (*next == '.') { 579 arg = next + 1; 580 l = strtol( arg, &next, 10 ); 581 if ( l < 0 || l > 0xff || next == arg || *next != '\0' ) 582 return -1; 583 i += l; 584 } 585 return ldap_pvt_tls_set_option( ld, option, &i ); 586 } 587 #ifdef HAVE_OPENSSL_CRL 588 case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */ 589 i = -1; 590 if ( strcasecmp( arg, "none" ) == 0 ) { 591 i = LDAP_OPT_X_TLS_CRL_NONE ; 592 } else if ( strcasecmp( arg, "peer" ) == 0 ) { 593 i = LDAP_OPT_X_TLS_CRL_PEER ; 594 } else if ( strcasecmp( arg, "all" ) == 0 ) { 595 i = LDAP_OPT_X_TLS_CRL_ALL ; 596 } 597 if (i >= 0) { 598 return ldap_pvt_tls_set_option( ld, option, &i ); 599 } 600 return -1; 601 #endif 602 } 603 return -1; 604 } 605 606 int 607 ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg ) 608 { 609 struct ldapoptions *lo; 610 611 if( option == LDAP_OPT_X_TLS_PACKAGE ) { 612 *(char **)arg = LDAP_STRDUP( tls_imp->ti_name ); 613 return 0; 614 } 615 616 if( ld != NULL ) { 617 assert( LDAP_VALID( ld ) ); 618 619 if( !LDAP_VALID( ld ) ) { 620 return LDAP_OPT_ERROR; 621 } 622 623 lo = &ld->ld_options; 624 625 } else { 626 /* Get pointer to global option structure */ 627 lo = LDAP_INT_GLOBAL_OPT(); 628 if ( lo == NULL ) { 629 return LDAP_NO_MEMORY; 630 } 631 } 632 633 switch( option ) { 634 case LDAP_OPT_X_TLS: 635 *(int *)arg = lo->ldo_tls_mode; 636 break; 637 case LDAP_OPT_X_TLS_CTX: 638 *(void **)arg = lo->ldo_tls_ctx; 639 if ( lo->ldo_tls_ctx ) { 640 tls_ctx_ref( lo->ldo_tls_ctx ); 641 } 642 break; 643 case LDAP_OPT_X_TLS_CACERTFILE: 644 *(char **)arg = lo->ldo_tls_cacertfile ? 645 LDAP_STRDUP( lo->ldo_tls_cacertfile ) : NULL; 646 break; 647 case LDAP_OPT_X_TLS_CACERTDIR: 648 *(char **)arg = lo->ldo_tls_cacertdir ? 649 LDAP_STRDUP( lo->ldo_tls_cacertdir ) : NULL; 650 break; 651 case LDAP_OPT_X_TLS_CERTFILE: 652 *(char **)arg = lo->ldo_tls_certfile ? 653 LDAP_STRDUP( lo->ldo_tls_certfile ) : NULL; 654 break; 655 case LDAP_OPT_X_TLS_KEYFILE: 656 *(char **)arg = lo->ldo_tls_keyfile ? 657 LDAP_STRDUP( lo->ldo_tls_keyfile ) : NULL; 658 break; 659 case LDAP_OPT_X_TLS_DHFILE: 660 *(char **)arg = lo->ldo_tls_dhfile ? 661 LDAP_STRDUP( lo->ldo_tls_dhfile ) : NULL; 662 break; 663 case LDAP_OPT_X_TLS_ECNAME: 664 *(char **)arg = lo->ldo_tls_ecname ? 665 LDAP_STRDUP( lo->ldo_tls_ecname ) : NULL; 666 break; 667 case LDAP_OPT_X_TLS_CRLFILE: /* GnuTLS only */ 668 *(char **)arg = lo->ldo_tls_crlfile ? 669 LDAP_STRDUP( lo->ldo_tls_crlfile ) : NULL; 670 break; 671 case LDAP_OPT_X_TLS_REQUIRE_CERT: 672 *(int *)arg = lo->ldo_tls_require_cert; 673 break; 674 #ifdef HAVE_OPENSSL_CRL 675 case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */ 676 *(int *)arg = lo->ldo_tls_crlcheck; 677 break; 678 #endif 679 case LDAP_OPT_X_TLS_CIPHER_SUITE: 680 *(char **)arg = lo->ldo_tls_ciphersuite ? 681 LDAP_STRDUP( lo->ldo_tls_ciphersuite ) : NULL; 682 break; 683 case LDAP_OPT_X_TLS_PROTOCOL_MIN: 684 *(int *)arg = lo->ldo_tls_protocol_min; 685 break; 686 case LDAP_OPT_X_TLS_RANDOM_FILE: 687 *(char **)arg = lo->ldo_tls_randfile ? 688 LDAP_STRDUP( lo->ldo_tls_randfile ) : NULL; 689 break; 690 case LDAP_OPT_X_TLS_SSL_CTX: { 691 void *retval = 0; 692 if ( ld != NULL ) { 693 LDAPConn *conn = ld->ld_defconn; 694 if ( conn != NULL ) { 695 Sockbuf *sb = conn->lconn_sb; 696 retval = ldap_pvt_tls_sb_ctx( sb ); 697 } 698 } 699 *(void **)arg = retval; 700 break; 701 } 702 case LDAP_OPT_X_TLS_CONNECT_CB: 703 *(LDAP_TLS_CONNECT_CB **)arg = lo->ldo_tls_connect_cb; 704 break; 705 case LDAP_OPT_X_TLS_CONNECT_ARG: 706 *(void **)arg = lo->ldo_tls_connect_arg; 707 break; 708 default: 709 return -1; 710 } 711 return 0; 712 } 713 714 int 715 ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg ) 716 { 717 struct ldapoptions *lo; 718 719 if( ld != NULL ) { 720 assert( LDAP_VALID( ld ) ); 721 722 if( !LDAP_VALID( ld ) ) { 723 return LDAP_OPT_ERROR; 724 } 725 726 lo = &ld->ld_options; 727 728 } else { 729 /* Get pointer to global option structure */ 730 lo = LDAP_INT_GLOBAL_OPT(); 731 if ( lo == NULL ) { 732 return LDAP_NO_MEMORY; 733 } 734 } 735 736 switch( option ) { 737 case LDAP_OPT_X_TLS: 738 if ( !arg ) return -1; 739 740 switch( *(int *) arg ) { 741 case LDAP_OPT_X_TLS_NEVER: 742 case LDAP_OPT_X_TLS_DEMAND: 743 case LDAP_OPT_X_TLS_ALLOW: 744 case LDAP_OPT_X_TLS_TRY: 745 case LDAP_OPT_X_TLS_HARD: 746 if (lo != NULL) { 747 lo->ldo_tls_mode = *(int *)arg; 748 } 749 750 return 0; 751 } 752 return -1; 753 754 case LDAP_OPT_X_TLS_CTX: 755 if ( lo->ldo_tls_ctx ) 756 ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx ); 757 lo->ldo_tls_ctx = arg; 758 tls_ctx_ref( lo->ldo_tls_ctx ); 759 return 0; 760 case LDAP_OPT_X_TLS_CONNECT_CB: 761 lo->ldo_tls_connect_cb = (LDAP_TLS_CONNECT_CB *)arg; 762 return 0; 763 case LDAP_OPT_X_TLS_CONNECT_ARG: 764 lo->ldo_tls_connect_arg = arg; 765 return 0; 766 case LDAP_OPT_X_TLS_CACERTFILE: 767 if ( lo->ldo_tls_cacertfile ) LDAP_FREE( lo->ldo_tls_cacertfile ); 768 lo->ldo_tls_cacertfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 769 return 0; 770 case LDAP_OPT_X_TLS_CACERTDIR: 771 if ( lo->ldo_tls_cacertdir ) LDAP_FREE( lo->ldo_tls_cacertdir ); 772 lo->ldo_tls_cacertdir = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 773 return 0; 774 case LDAP_OPT_X_TLS_CERTFILE: 775 if ( lo->ldo_tls_certfile ) LDAP_FREE( lo->ldo_tls_certfile ); 776 lo->ldo_tls_certfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 777 return 0; 778 case LDAP_OPT_X_TLS_KEYFILE: 779 if ( lo->ldo_tls_keyfile ) LDAP_FREE( lo->ldo_tls_keyfile ); 780 lo->ldo_tls_keyfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 781 return 0; 782 case LDAP_OPT_X_TLS_DHFILE: 783 if ( lo->ldo_tls_dhfile ) LDAP_FREE( lo->ldo_tls_dhfile ); 784 lo->ldo_tls_dhfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 785 return 0; 786 case LDAP_OPT_X_TLS_ECNAME: 787 if ( lo->ldo_tls_ecname ) LDAP_FREE( lo->ldo_tls_ecname ); 788 lo->ldo_tls_ecname = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 789 return 0; 790 case LDAP_OPT_X_TLS_CRLFILE: /* GnuTLS only */ 791 if ( lo->ldo_tls_crlfile ) LDAP_FREE( lo->ldo_tls_crlfile ); 792 lo->ldo_tls_crlfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 793 return 0; 794 case LDAP_OPT_X_TLS_REQUIRE_CERT: 795 if ( !arg ) return -1; 796 switch( *(int *) arg ) { 797 case LDAP_OPT_X_TLS_NEVER: 798 case LDAP_OPT_X_TLS_DEMAND: 799 case LDAP_OPT_X_TLS_ALLOW: 800 case LDAP_OPT_X_TLS_TRY: 801 case LDAP_OPT_X_TLS_HARD: 802 lo->ldo_tls_require_cert = * (int *) arg; 803 return 0; 804 } 805 return -1; 806 #ifdef HAVE_OPENSSL_CRL 807 case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */ 808 if ( !arg ) return -1; 809 switch( *(int *) arg ) { 810 case LDAP_OPT_X_TLS_CRL_NONE: 811 case LDAP_OPT_X_TLS_CRL_PEER: 812 case LDAP_OPT_X_TLS_CRL_ALL: 813 lo->ldo_tls_crlcheck = * (int *) arg; 814 return 0; 815 } 816 return -1; 817 #endif 818 case LDAP_OPT_X_TLS_CIPHER_SUITE: 819 if ( lo->ldo_tls_ciphersuite ) LDAP_FREE( lo->ldo_tls_ciphersuite ); 820 lo->ldo_tls_ciphersuite = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 821 return 0; 822 823 case LDAP_OPT_X_TLS_PROTOCOL_MIN: 824 if ( !arg ) return -1; 825 lo->ldo_tls_protocol_min = *(int *)arg; 826 return 0; 827 case LDAP_OPT_X_TLS_RANDOM_FILE: 828 if ( ld != NULL ) 829 return -1; 830 if ( lo->ldo_tls_randfile ) LDAP_FREE (lo->ldo_tls_randfile ); 831 lo->ldo_tls_randfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL; 832 break; 833 case LDAP_OPT_X_TLS_NEWCTX: 834 if ( !arg ) return -1; 835 if ( lo->ldo_tls_ctx ) 836 ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx ); 837 lo->ldo_tls_ctx = NULL; 838 return ldap_int_tls_init_ctx( lo, *(int *)arg ); 839 default: 840 return -1; 841 } 842 return 0; 843 } 844 845 int 846 ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv ) 847 { 848 Sockbuf *sb; 849 char *host; 850 void *ssl; 851 int ret, async; 852 #ifdef LDAP_USE_NON_BLOCKING_TLS 853 struct timeval start_time_tv, tv, tv0; 854 ber_socket_t sd = AC_SOCKET_ERROR; 855 #endif /* LDAP_USE_NON_BLOCKING_TLS */ 856 857 if ( !conn ) 858 return LDAP_PARAM_ERROR; 859 860 sb = conn->lconn_sb; 861 if( srv ) { 862 host = srv->lud_host; 863 } else { 864 host = conn->lconn_server->lud_host; 865 } 866 867 /* avoid NULL host */ 868 if( host == NULL ) { 869 host = "localhost"; 870 } 871 872 (void) tls_init( tls_imp ); 873 874 #ifdef LDAP_USE_NON_BLOCKING_TLS 875 /* 876 * Use non-blocking io during SSL Handshake when a timeout is configured 877 */ 878 async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC ); 879 if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) { 880 if ( !async ) { 881 /* if async, this has already been set */ 882 ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 ); 883 } 884 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd ); 885 tv = ld->ld_options.ldo_tm_net; 886 tv0 = tv; 887 #ifdef HAVE_GETTIMEOFDAY 888 gettimeofday( &start_time_tv, NULL ); 889 #else /* ! HAVE_GETTIMEOFDAY */ 890 time( &start_time_tv.tv_sec ); 891 start_time_tv.tv_usec = 0; 892 #endif /* ! HAVE_GETTIMEOFDAY */ 893 } 894 895 #endif /* LDAP_USE_NON_BLOCKING_TLS */ 896 897 ld->ld_errno = LDAP_SUCCESS; 898 ret = ldap_int_tls_connect( ld, conn, host ); 899 900 /* this mainly only happens for non-blocking io 901 * but can also happen when the handshake is too 902 * big for a single network message. 903 */ 904 while ( ret > 0 ) { 905 #ifdef LDAP_USE_NON_BLOCKING_TLS 906 if ( async ) { 907 struct timeval curr_time_tv, delta_tv; 908 int wr=0; 909 910 if ( sb->sb_trans_needs_read ) { 911 wr=0; 912 } else if ( sb->sb_trans_needs_write ) { 913 wr=1; 914 } 915 Debug1( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ldap_int_tls_connect needs %s\n", 916 wr ? "write": "read" ); 917 918 /* This is mostly copied from result.c:wait4msg(), should 919 * probably be moved into a separate function */ 920 #ifdef HAVE_GETTIMEOFDAY 921 gettimeofday( &curr_time_tv, NULL ); 922 #else /* ! HAVE_GETTIMEOFDAY */ 923 time( &curr_time_tv.tv_sec ); 924 curr_time_tv.tv_usec = 0; 925 #endif /* ! HAVE_GETTIMEOFDAY */ 926 927 /* delta = curr - start */ 928 delta_tv.tv_sec = curr_time_tv.tv_sec - start_time_tv.tv_sec; 929 delta_tv.tv_usec = curr_time_tv.tv_usec - start_time_tv.tv_usec; 930 if ( delta_tv.tv_usec < 0 ) { 931 delta_tv.tv_sec--; 932 delta_tv.tv_usec += 1000000; 933 } 934 935 /* tv0 < delta ? */ 936 if ( ( tv0.tv_sec < delta_tv.tv_sec ) || 937 ( ( tv0.tv_sec == delta_tv.tv_sec ) && 938 ( tv0.tv_usec < delta_tv.tv_usec ) ) ) 939 { 940 ret = -1; 941 ld->ld_errno = LDAP_TIMEOUT; 942 break; 943 } 944 /* timeout -= delta_time */ 945 tv0.tv_sec -= delta_tv.tv_sec; 946 tv0.tv_usec -= delta_tv.tv_usec; 947 if ( tv0.tv_usec < 0 ) { 948 tv0.tv_sec--; 949 tv0.tv_usec += 1000000; 950 } 951 start_time_tv.tv_sec = curr_time_tv.tv_sec; 952 start_time_tv.tv_usec = curr_time_tv.tv_usec; 953 tv = tv0; 954 Debug3( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ld %p %ld s %ld us to go\n", 955 (void *)ld, (long) tv.tv_sec, (long) tv.tv_usec ); 956 ret = ldap_int_poll( ld, sd, &tv, wr); 957 if ( ret < 0 ) { 958 ld->ld_errno = LDAP_TIMEOUT; 959 break; 960 } 961 } 962 #endif /* LDAP_USE_NON_BLOCKING_TLS */ 963 ret = ldap_int_tls_connect( ld, conn, host ); 964 } 965 966 if ( ret < 0 ) { 967 if ( ld->ld_errno == LDAP_SUCCESS ) 968 ld->ld_errno = LDAP_CONNECT_ERROR; 969 return (ld->ld_errno); 970 } 971 972 return LDAP_SUCCESS; 973 } 974 975 void * 976 ldap_pvt_tls_sb_ctx( Sockbuf *sb ) 977 { 978 void *p = NULL; 979 980 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p ); 981 return p; 982 } 983 984 int 985 ldap_pvt_tls_get_strength( void *s ) 986 { 987 tls_session *session = s; 988 989 return tls_imp->ti_session_strength( session ); 990 } 991 992 int 993 ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func, unsigned flags ) 994 { 995 tls_session *session = s; 996 struct berval der_dn; 997 int rc; 998 999 rc = tls_imp->ti_session_my_dn( session, &der_dn ); 1000 if ( rc == LDAP_SUCCESS ) 1001 rc = ldap_X509dn2bv(&der_dn, dn, (LDAPDN_rewrite_func *)func, flags ); 1002 return rc; 1003 } 1004 #endif /* HAVE_TLS */ 1005 1006 int 1007 ldap_start_tls( LDAP *ld, 1008 LDAPControl **serverctrls, 1009 LDAPControl **clientctrls, 1010 int *msgidp ) 1011 { 1012 return ldap_extended_operation( ld, LDAP_EXOP_START_TLS, 1013 NULL, serverctrls, clientctrls, msgidp ); 1014 } 1015 1016 int 1017 ldap_install_tls( LDAP *ld ) 1018 { 1019 #ifndef HAVE_TLS 1020 return LDAP_NOT_SUPPORTED; 1021 #else 1022 if ( ldap_tls_inplace( ld ) ) { 1023 return LDAP_LOCAL_ERROR; 1024 } 1025 1026 return ldap_int_tls_start( ld, ld->ld_defconn, NULL ); 1027 #endif 1028 } 1029 1030 int 1031 ldap_start_tls_s ( LDAP *ld, 1032 LDAPControl **serverctrls, 1033 LDAPControl **clientctrls ) 1034 { 1035 #ifndef HAVE_TLS 1036 return LDAP_NOT_SUPPORTED; 1037 #else 1038 int rc; 1039 char *rspoid = NULL; 1040 struct berval *rspdata = NULL; 1041 1042 /* XXYYZ: this initiates operation only on default connection! */ 1043 1044 if ( ldap_tls_inplace( ld ) ) { 1045 return LDAP_LOCAL_ERROR; 1046 } 1047 1048 rc = ldap_extended_operation_s( ld, LDAP_EXOP_START_TLS, 1049 NULL, serverctrls, clientctrls, &rspoid, &rspdata ); 1050 1051 if ( rspoid != NULL ) { 1052 LDAP_FREE(rspoid); 1053 } 1054 1055 if ( rspdata != NULL ) { 1056 ber_bvfree( rspdata ); 1057 } 1058 1059 if ( rc == LDAP_SUCCESS ) { 1060 rc = ldap_int_tls_start( ld, ld->ld_defconn, NULL ); 1061 } 1062 1063 return rc; 1064 #endif 1065 } 1066 1067 /* These tags probably all belong in lber.h, but they're 1068 * not normally encountered when processing LDAP, so maybe 1069 * they belong somewhere else instead. 1070 */ 1071 1072 #define LBER_TAG_OID ((ber_tag_t) 0x06UL) 1073 1074 /* Tags for string types used in a DirectoryString. 1075 * 1076 * Note that IA5string is not one of the defined choices for 1077 * DirectoryString in X.520, but it gets used for email AVAs. 1078 */ 1079 #define LBER_TAG_UTF8 ((ber_tag_t) 0x0cUL) 1080 #define LBER_TAG_PRINTABLE ((ber_tag_t) 0x13UL) 1081 #define LBER_TAG_TELETEX ((ber_tag_t) 0x14UL) 1082 #define LBER_TAG_IA5 ((ber_tag_t) 0x16UL) 1083 #define LBER_TAG_UNIVERSAL ((ber_tag_t) 0x1cUL) 1084 #define LBER_TAG_BMP ((ber_tag_t) 0x1eUL) 1085 1086 static oid_name * 1087 find_oid( struct berval *oid ) 1088 { 1089 int i; 1090 1091 for ( i=0; !BER_BVISNULL( &oids[i].oid ); i++ ) { 1092 if ( oids[i].oid.bv_len != oid->bv_len ) continue; 1093 if ( !strcmp( oids[i].oid.bv_val, oid->bv_val )) 1094 return &oids[i]; 1095 } 1096 return NULL; 1097 } 1098 1099 /* Converts BER Bitstring value to LDAP BitString value (RFC4517) 1100 * 1101 * berValue : IN 1102 * rfc4517Value: OUT 1103 * 1104 * berValue and ldapValue should not be NULL 1105 */ 1106 1107 #define BITS_PER_BYTE 8 1108 #define SQUOTE_LENGTH 1 1109 #define B_CHAR_LENGTH 1 1110 #define STR_OVERHEAD (2*SQUOTE_LENGTH + B_CHAR_LENGTH) 1111 1112 static int 1113 der_to_ldap_BitString (struct berval *berValue, 1114 struct berval *ldapValue) 1115 { 1116 ber_len_t bitPadding=0; 1117 ber_len_t bits, maxBits; 1118 char *tmpStr; 1119 unsigned char byte; 1120 ber_len_t bitLength; 1121 ber_len_t valLen; 1122 unsigned char* valPtr; 1123 1124 ldapValue->bv_len=0; 1125 ldapValue->bv_val=NULL; 1126 1127 /* Gets padding and points to binary data */ 1128 valLen=berValue->bv_len; 1129 valPtr=(unsigned char*)berValue->bv_val; 1130 if (valLen) { 1131 bitPadding=(ber_len_t)(valPtr[0]); 1132 valLen--; 1133 valPtr++; 1134 } 1135 /* If Block is non DER encoding fixes to DER encoding */ 1136 if (bitPadding >= BITS_PER_BYTE) { 1137 if (valLen*BITS_PER_BYTE > bitPadding ) { 1138 valLen-=(bitPadding/BITS_PER_BYTE); 1139 bitPadding%=BITS_PER_BYTE; 1140 } else { 1141 valLen=0; 1142 bitPadding=0; 1143 } 1144 } 1145 /* Just in case bad encoding */ 1146 if (valLen*BITS_PER_BYTE < bitPadding ) { 1147 bitPadding=0; 1148 valLen=0; 1149 } 1150 1151 /* Gets buffer to hold RFC4517 Bit String format */ 1152 bitLength=valLen*BITS_PER_BYTE-bitPadding; 1153 tmpStr=LDAP_MALLOC(bitLength + STR_OVERHEAD + 1); 1154 1155 if (!tmpStr) 1156 return LDAP_NO_MEMORY; 1157 1158 ldapValue->bv_val=tmpStr; 1159 ldapValue->bv_len=bitLength + STR_OVERHEAD; 1160 1161 /* Formatting in '*binary-digit'B format */ 1162 maxBits=BITS_PER_BYTE; 1163 *tmpStr++ ='\''; 1164 while(valLen) { 1165 byte=*valPtr; 1166 if (valLen==1) 1167 maxBits-=bitPadding; 1168 for (bits=0; bits<maxBits; bits++) { 1169 if (0x80 & byte) 1170 *tmpStr='1'; 1171 else 1172 *tmpStr='0'; 1173 tmpStr++; 1174 byte<<=1; 1175 } 1176 valPtr++; 1177 valLen--; 1178 } 1179 *tmpStr++ ='\''; 1180 *tmpStr++ ='B'; 1181 *tmpStr=0; 1182 1183 return LDAP_SUCCESS; 1184 } 1185 1186 /* Convert a structured DN from an X.509 certificate into an LDAPV3 DN. 1187 * x509_name must be raw DER. If func is non-NULL, the 1188 * constructed DN will use numeric OIDs to identify attributeTypes, 1189 * and the func() will be invoked to rewrite the DN with the given 1190 * flags. 1191 * 1192 * Otherwise the DN will use shortNames from a hardcoded table. 1193 */ 1194 int 1195 ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, 1196 unsigned flags ) 1197 { 1198 LDAPDN newDN; 1199 LDAPRDN newRDN; 1200 LDAPAVA *newAVA, *baseAVA; 1201 BerElementBuffer berbuf; 1202 BerElement *ber = (BerElement *)&berbuf; 1203 char oids[8192], *oidptr = oids, *oidbuf = NULL; 1204 void *ptrs[2048]; 1205 char *dn_end, *rdn_end; 1206 int i, navas, nrdns, rc = LDAP_SUCCESS; 1207 size_t dnsize, oidrem = sizeof(oids), oidsize = 0; 1208 int csize; 1209 ber_tag_t tag; 1210 ber_len_t len; 1211 oid_name *oidname; 1212 1213 struct berval Oid, Val, oid2, *in = x509_name; 1214 1215 assert( bv != NULL ); 1216 1217 bv->bv_len = 0; 1218 bv->bv_val = NULL; 1219 1220 navas = 0; 1221 nrdns = 0; 1222 1223 /* A DN is a SEQUENCE of RDNs. An RDN is a SET of AVAs. 1224 * An AVA is a SEQUENCE of attr and value. 1225 * Count the number of AVAs and RDNs 1226 */ 1227 ber_init2( ber, in, LBER_USE_DER ); 1228 tag = ber_peek_tag( ber, &len ); 1229 if ( tag != LBER_SEQUENCE ) 1230 return LDAP_DECODING_ERROR; 1231 1232 for ( tag = ber_first_element( ber, &len, &dn_end ); 1233 tag == LBER_SET; 1234 tag = ber_next_element( ber, &len, dn_end )) { 1235 nrdns++; 1236 for ( tag = ber_first_element( ber, &len, &rdn_end ); 1237 tag == LBER_SEQUENCE; 1238 tag = ber_next_element( ber, &len, rdn_end )) { 1239 tag = ber_skip_tag( ber, &len ); 1240 ber_skip_data( ber, len ); 1241 navas++; 1242 } 1243 } 1244 1245 /* Allocate the DN/RDN/AVA stuff as a single block */ 1246 dnsize = sizeof(LDAPRDN) * (nrdns+1); 1247 dnsize += sizeof(LDAPAVA *) * (navas+nrdns); 1248 dnsize += sizeof(LDAPAVA) * navas; 1249 if (dnsize > sizeof(ptrs)) { 1250 newDN = (LDAPDN)LDAP_MALLOC( dnsize ); 1251 if ( newDN == NULL ) 1252 return LDAP_NO_MEMORY; 1253 } else { 1254 newDN = (LDAPDN)(char *)ptrs; 1255 } 1256 1257 newDN[nrdns] = NULL; 1258 newRDN = (LDAPRDN)(newDN + nrdns+1); 1259 newAVA = (LDAPAVA *)(newRDN + navas + nrdns); 1260 baseAVA = newAVA; 1261 1262 /* Rewind and start extracting */ 1263 ber_rewind( ber ); 1264 1265 tag = ber_first_element( ber, &len, &dn_end ); 1266 for ( i = nrdns - 1; i >= 0; i-- ) { 1267 newDN[i] = newRDN; 1268 1269 for ( tag = ber_first_element( ber, &len, &rdn_end ); 1270 tag == LBER_SEQUENCE; 1271 tag = ber_next_element( ber, &len, rdn_end )) { 1272 1273 *newRDN++ = newAVA; 1274 tag = ber_skip_tag( ber, &len ); 1275 tag = ber_get_stringbv( ber, &Oid, LBER_BV_NOTERM ); 1276 if ( tag != LBER_TAG_OID ) { 1277 rc = LDAP_DECODING_ERROR; 1278 goto nomem; 1279 } 1280 1281 oid2.bv_val = oidptr; 1282 oid2.bv_len = oidrem; 1283 if ( ber_decode_oid( &Oid, &oid2 ) < 0 ) { 1284 rc = LDAP_DECODING_ERROR; 1285 goto nomem; 1286 } 1287 oidname = find_oid( &oid2 ); 1288 if ( !oidname ) { 1289 newAVA->la_attr = oid2; 1290 oidptr += oid2.bv_len + 1; 1291 oidrem -= oid2.bv_len + 1; 1292 1293 /* Running out of OID buffer space? */ 1294 if (oidrem < 128) { 1295 if ( oidsize == 0 ) { 1296 oidsize = sizeof(oids) * 2; 1297 oidrem = oidsize; 1298 oidbuf = LDAP_MALLOC( oidsize ); 1299 if ( oidbuf == NULL ) goto nomem; 1300 oidptr = oidbuf; 1301 } else { 1302 char *old = oidbuf; 1303 oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 ); 1304 if ( oidbuf == NULL ) goto nomem; 1305 /* Buffer moved! Fix AVA pointers */ 1306 if ( old != oidbuf ) { 1307 LDAPAVA *a; 1308 long dif = oidbuf - old; 1309 1310 for (a=baseAVA; a<=newAVA; a++){ 1311 if (a->la_attr.bv_val >= old && 1312 a->la_attr.bv_val <= (old + oidsize)) 1313 a->la_attr.bv_val += dif; 1314 } 1315 } 1316 oidptr = oidbuf + oidsize - oidrem; 1317 oidrem += oidsize; 1318 oidsize *= 2; 1319 } 1320 } 1321 } else { 1322 if ( func ) { 1323 newAVA->la_attr = oidname->oid; 1324 } else { 1325 newAVA->la_attr = oidname->name; 1326 } 1327 } 1328 newAVA->la_private = NULL; 1329 newAVA->la_flags = LDAP_AVA_STRING; 1330 tag = ber_get_stringbv( ber, &Val, LBER_BV_NOTERM ); 1331 switch(tag) { 1332 case LBER_TAG_UNIVERSAL: 1333 /* This uses 32-bit ISO 10646-1 */ 1334 csize = 4; goto to_utf8; 1335 case LBER_TAG_BMP: 1336 /* This uses 16-bit ISO 10646-1 */ 1337 csize = 2; goto to_utf8; 1338 case LBER_TAG_TELETEX: 1339 /* This uses 8-bit, assume ISO 8859-1 */ 1340 csize = 1; 1341 to_utf8: rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value ); 1342 newAVA->la_flags |= LDAP_AVA_NONPRINTABLE; 1343 allocd: 1344 newAVA->la_flags |= LDAP_AVA_FREE_VALUE; 1345 if (rc != LDAP_SUCCESS) goto nomem; 1346 break; 1347 case LBER_TAG_UTF8: 1348 newAVA->la_flags |= LDAP_AVA_NONPRINTABLE; 1349 /* This is already in UTF-8 encoding */ 1350 case LBER_TAG_IA5: 1351 case LBER_TAG_PRINTABLE: 1352 /* These are always 7-bit strings */ 1353 newAVA->la_value = Val; 1354 break; 1355 case LBER_BITSTRING: 1356 /* X.690 bitString value converted to RFC4517 Bit String */ 1357 rc = der_to_ldap_BitString( &Val, &newAVA->la_value ); 1358 goto allocd; 1359 default: 1360 /* Not a string type at all */ 1361 newAVA->la_flags = 0; 1362 newAVA->la_value = Val; 1363 break; 1364 } 1365 newAVA++; 1366 } 1367 *newRDN++ = NULL; 1368 tag = ber_next_element( ber, &len, dn_end ); 1369 } 1370 1371 if ( func ) { 1372 rc = func( newDN, flags, NULL ); 1373 if ( rc != LDAP_SUCCESS ) 1374 goto nomem; 1375 } 1376 1377 rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL ); 1378 1379 nomem: 1380 for (;baseAVA < newAVA; baseAVA++) { 1381 if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR) 1382 LDAP_FREE( baseAVA->la_attr.bv_val ); 1383 if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE) 1384 LDAP_FREE( baseAVA->la_value.bv_val ); 1385 } 1386 1387 if ( oidsize != 0 ) 1388 LDAP_FREE( oidbuf ); 1389 if ( newDN != (LDAPDN)(char *) ptrs ) 1390 LDAP_FREE( newDN ); 1391 return rc; 1392 } 1393 1394