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