1 /* $NetBSD: tls_g.c,v 1.1.1.3 2014/05/28 09:58:42 tron Exp $ */ 2 3 /* tls_g.c - Handle tls/ssl using GNUTLS. */ 4 /* $OpenLDAP$ */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 2008-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: GNUTLS support written by Howard Chu and 19 * Emily Backes; sponsored by The Written Word (thewrittenword.com) 20 * and Stanford University (stanford.edu). 21 */ 22 23 #include "portable.h" 24 25 #ifdef HAVE_GNUTLS 26 27 #include "ldap_config.h" 28 29 #include <stdio.h> 30 31 #include <ac/stdlib.h> 32 #include <ac/errno.h> 33 #include <ac/socket.h> 34 #include <ac/string.h> 35 #include <ac/ctype.h> 36 #include <ac/time.h> 37 #include <ac/unistd.h> 38 #include <ac/param.h> 39 #include <ac/dirent.h> 40 #include <sys/stat.h> 41 #include <fcntl.h> 42 43 #include "ldap-int.h" 44 #include "ldap-tls.h" 45 46 #include <gnutls/gnutls.h> 47 #include <gnutls/x509.h> 48 #include <gcrypt.h> 49 50 #define DH_BITS (1024) 51 52 #if LIBGNUTLS_VERSION_NUMBER >= 0x020200 53 #define HAVE_CIPHERSUITES 1 54 /* This is a kludge. gcrypt 1.4.x has support. Recent GnuTLS requires gcrypt 1.4.x 55 * but that dependency isn't reflected in their configure script, resulting in 56 * build errors on older gcrypt. So, if they have a working build environment, 57 * assume gcrypt is new enough. 58 */ 59 #define HAVE_GCRYPT_RAND 1 60 #else 61 #undef HAVE_CIPHERSUITES 62 #undef HAVE_GCRYPT_RAND 63 #endif 64 65 #ifndef HAVE_CIPHERSUITES 66 /* Versions prior to 2.2.0 didn't handle cipher suites, so we had to 67 * kludge them ourselves. 68 */ 69 typedef struct tls_cipher_suite { 70 const char *name; 71 gnutls_kx_algorithm_t kx; 72 gnutls_cipher_algorithm_t cipher; 73 gnutls_mac_algorithm_t mac; 74 gnutls_protocol_t version; 75 } tls_cipher_suite; 76 #endif 77 78 typedef struct tlsg_ctx { 79 struct ldapoptions *lo; 80 gnutls_certificate_credentials_t cred; 81 gnutls_dh_params_t dh_params; 82 unsigned long verify_depth; 83 int refcount; 84 #ifdef HAVE_CIPHERSUITES 85 gnutls_priority_t prios; 86 #else 87 int *kx_list; 88 int *cipher_list; 89 int *mac_list; 90 #endif 91 #ifdef LDAP_R_COMPILE 92 ldap_pvt_thread_mutex_t ref_mutex; 93 #endif 94 } tlsg_ctx; 95 96 typedef struct tlsg_session { 97 gnutls_session_t session; 98 tlsg_ctx *ctx; 99 struct berval peer_der_dn; 100 } tlsg_session; 101 102 #ifndef HAVE_CIPHERSUITES 103 static tls_cipher_suite *tlsg_ciphers; 104 static int tlsg_n_ciphers; 105 #endif 106 107 static int tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites ); 108 static int tlsg_cert_verify( tlsg_session *s ); 109 110 #ifdef LDAP_R_COMPILE 111 112 static int 113 tlsg_mutex_init( void **priv ) 114 { 115 int err = 0; 116 ldap_pvt_thread_mutex_t *lock = LDAP_MALLOC( sizeof( ldap_pvt_thread_mutex_t )); 117 118 if ( !lock ) 119 err = ENOMEM; 120 if ( !err ) { 121 err = ldap_pvt_thread_mutex_init( lock ); 122 if ( err ) 123 LDAP_FREE( lock ); 124 else 125 *priv = lock; 126 } 127 return err; 128 } 129 130 static int 131 tlsg_mutex_destroy( void **lock ) 132 { 133 int err = ldap_pvt_thread_mutex_destroy( *lock ); 134 LDAP_FREE( *lock ); 135 return err; 136 } 137 138 static int 139 tlsg_mutex_lock( void **lock ) 140 { 141 return ldap_pvt_thread_mutex_lock( *lock ); 142 } 143 144 static int 145 tlsg_mutex_unlock( void **lock ) 146 { 147 return ldap_pvt_thread_mutex_unlock( *lock ); 148 } 149 150 static struct gcry_thread_cbs tlsg_thread_cbs = { 151 GCRY_THREAD_OPTION_USER, 152 NULL, 153 tlsg_mutex_init, 154 tlsg_mutex_destroy, 155 tlsg_mutex_lock, 156 tlsg_mutex_unlock, 157 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 158 }; 159 160 static void 161 tlsg_thr_init( void ) 162 { 163 gcry_control (GCRYCTL_SET_THREAD_CBS, &tlsg_thread_cbs); 164 } 165 #endif /* LDAP_R_COMPILE */ 166 167 /* 168 * Initialize TLS subsystem. Should be called only once. 169 */ 170 static int 171 tlsg_init( void ) 172 { 173 #ifdef HAVE_GCRYPT_RAND 174 struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT(); 175 if ( lo->ldo_tls_randfile && 176 gcry_control( GCRYCTL_SET_RNDEGD_SOCKET, lo->ldo_tls_randfile )) { 177 Debug( LDAP_DEBUG_ANY, 178 "TLS: gcry_control GCRYCTL_SET_RNDEGD_SOCKET failed\n", 179 0, 0, 0); 180 return -1; 181 } 182 #endif 183 184 gnutls_global_init(); 185 186 #ifndef HAVE_CIPHERSUITES 187 /* GNUtls cipher suite handling: The library ought to parse suite 188 * names for us, but it doesn't. It will return a list of suite names 189 * that it supports, so we can do parsing ourselves. It ought to tell 190 * us how long the list is, but it doesn't do that either, so we just 191 * have to count it manually... 192 */ 193 { 194 int i = 0; 195 tls_cipher_suite *ptr, tmp; 196 char cs_id[2]; 197 198 while ( gnutls_cipher_suite_info( i, cs_id, &tmp.kx, &tmp.cipher, 199 &tmp.mac, &tmp.version )) 200 i++; 201 tlsg_n_ciphers = i; 202 203 /* Store a copy */ 204 tlsg_ciphers = LDAP_MALLOC(tlsg_n_ciphers * sizeof(tls_cipher_suite)); 205 if ( !tlsg_ciphers ) 206 return -1; 207 for ( i=0; i<tlsg_n_ciphers; i++ ) { 208 tlsg_ciphers[i].name = gnutls_cipher_suite_info( i, cs_id, 209 &tlsg_ciphers[i].kx, &tlsg_ciphers[i].cipher, &tlsg_ciphers[i].mac, 210 &tlsg_ciphers[i].version ); 211 } 212 } 213 #endif 214 return 0; 215 } 216 217 /* 218 * Tear down the TLS subsystem. Should only be called once. 219 */ 220 static void 221 tlsg_destroy( void ) 222 { 223 #ifndef HAVE_CIPHERSUITES 224 LDAP_FREE( tlsg_ciphers ); 225 tlsg_ciphers = NULL; 226 tlsg_n_ciphers = 0; 227 #endif 228 gnutls_global_deinit(); 229 } 230 231 static tls_ctx * 232 tlsg_ctx_new ( struct ldapoptions *lo ) 233 { 234 tlsg_ctx *ctx; 235 236 ctx = ber_memcalloc ( 1, sizeof (*ctx) ); 237 if ( ctx ) { 238 ctx->lo = lo; 239 if ( gnutls_certificate_allocate_credentials( &ctx->cred )) { 240 ber_memfree( ctx ); 241 return NULL; 242 } 243 ctx->refcount = 1; 244 #ifdef HAVE_CIPHERSUITES 245 gnutls_priority_init( &ctx->prios, "NORMAL", NULL ); 246 #endif 247 #ifdef LDAP_R_COMPILE 248 ldap_pvt_thread_mutex_init( &ctx->ref_mutex ); 249 #endif 250 } 251 return (tls_ctx *)ctx; 252 } 253 254 static void 255 tlsg_ctx_ref( tls_ctx *ctx ) 256 { 257 tlsg_ctx *c = (tlsg_ctx *)ctx; 258 LDAP_MUTEX_LOCK( &c->ref_mutex ); 259 c->refcount++; 260 LDAP_MUTEX_UNLOCK( &c->ref_mutex ); 261 } 262 263 static void 264 tlsg_ctx_free ( tls_ctx *ctx ) 265 { 266 tlsg_ctx *c = (tlsg_ctx *)ctx; 267 int refcount; 268 269 if ( !c ) return; 270 271 LDAP_MUTEX_LOCK( &c->ref_mutex ); 272 refcount = --c->refcount; 273 LDAP_MUTEX_UNLOCK( &c->ref_mutex ); 274 if ( refcount ) 275 return; 276 #ifdef HAVE_CIPHERSUITES 277 gnutls_priority_deinit( c->prios ); 278 #else 279 LDAP_FREE( c->kx_list ); 280 #endif 281 gnutls_certificate_free_credentials( c->cred ); 282 ber_memfree ( c ); 283 } 284 285 static int 286 tlsg_getfile( const char *path, gnutls_datum_t *buf ) 287 { 288 int rc = -1, fd; 289 struct stat st; 290 291 fd = open( path, O_RDONLY ); 292 if ( fd >= 0 && fstat( fd, &st ) == 0 ) { 293 buf->size = st.st_size; 294 buf->data = LDAP_MALLOC( st.st_size + 1 ); 295 if ( buf->data ) { 296 rc = read( fd, buf->data, st.st_size ); 297 close( fd ); 298 if ( rc < st.st_size ) 299 rc = -1; 300 else 301 rc = 0; 302 } 303 } 304 return rc; 305 } 306 307 /* This is the GnuTLS default */ 308 #define VERIFY_DEPTH 6 309 310 /* 311 * initialize a new TLS context 312 */ 313 static int 314 tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) 315 { 316 tlsg_ctx *ctx = lo->ldo_tls_ctx; 317 int rc; 318 319 if ( lo->ldo_tls_ciphersuite && 320 tlsg_parse_ciphers( ctx, lt->lt_ciphersuite )) { 321 Debug( LDAP_DEBUG_ANY, 322 "TLS: could not set cipher list %s.\n", 323 lo->ldo_tls_ciphersuite, 0, 0 ); 324 return -1; 325 } 326 327 if (lo->ldo_tls_cacertdir != NULL) { 328 Debug( LDAP_DEBUG_ANY, 329 "TLS: warning: cacertdir not implemented for gnutls\n", 330 NULL, NULL, NULL ); 331 } 332 333 if (lo->ldo_tls_cacertfile != NULL) { 334 rc = gnutls_certificate_set_x509_trust_file( 335 ctx->cred, 336 lt->lt_cacertfile, 337 GNUTLS_X509_FMT_PEM ); 338 if ( rc < 0 ) return -1; 339 } 340 341 if ( lo->ldo_tls_certfile && lo->ldo_tls_keyfile ) { 342 gnutls_x509_privkey_t key; 343 gnutls_datum_t buf; 344 gnutls_x509_crt_t certs[VERIFY_DEPTH]; 345 unsigned int max = VERIFY_DEPTH; 346 347 rc = gnutls_x509_privkey_init( &key ); 348 if ( rc ) return -1; 349 350 /* OpenSSL builds the cert chain for us, but GnuTLS 351 * expects it to be present in the certfile. If it's 352 * not, we have to build it ourselves. So we have to 353 * do some special checks here... 354 */ 355 rc = tlsg_getfile( lt->lt_keyfile, &buf ); 356 if ( rc ) return -1; 357 rc = gnutls_x509_privkey_import( key, &buf, 358 GNUTLS_X509_FMT_PEM ); 359 LDAP_FREE( buf.data ); 360 if ( rc < 0 ) return rc; 361 362 rc = tlsg_getfile( lt->lt_certfile, &buf ); 363 if ( rc ) return -1; 364 rc = gnutls_x509_crt_list_import( certs, &max, &buf, 365 GNUTLS_X509_FMT_PEM, 0 ); 366 LDAP_FREE( buf.data ); 367 if ( rc < 0 ) return rc; 368 369 /* If there's only one cert and it's not self-signed, 370 * then we have to build the cert chain. 371 */ 372 if ( max == 1 && !gnutls_x509_crt_check_issuer( certs[0], certs[0] )) { 373 gnutls_x509_crt_t *cas; 374 unsigned int i, j, ncas; 375 376 gnutls_certificate_get_x509_cas( ctx->cred, &cas, &ncas ); 377 for ( i = 1; i<VERIFY_DEPTH; i++ ) { 378 for ( j = 0; j<ncas; j++ ) { 379 if ( gnutls_x509_crt_check_issuer( certs[i-1], cas[j] )) { 380 certs[i] = cas[j]; 381 max++; 382 /* If this CA is self-signed, we're done */ 383 if ( gnutls_x509_crt_check_issuer( cas[j], cas[j] )) 384 j = ncas; 385 break; 386 } 387 } 388 /* only continue if we found a CA and it was not self-signed */ 389 if ( j == ncas ) 390 break; 391 } 392 } 393 rc = gnutls_certificate_set_x509_key( ctx->cred, certs, max, key ); 394 if ( rc ) return -1; 395 } else if ( lo->ldo_tls_certfile || lo->ldo_tls_keyfile ) { 396 Debug( LDAP_DEBUG_ANY, 397 "TLS: only one of certfile and keyfile specified\n", 398 NULL, NULL, NULL ); 399 return -1; 400 } 401 402 if ( lo->ldo_tls_dhfile ) { 403 Debug( LDAP_DEBUG_ANY, 404 "TLS: warning: ignoring dhfile\n", 405 NULL, NULL, NULL ); 406 } 407 408 if ( lo->ldo_tls_crlfile ) { 409 rc = gnutls_certificate_set_x509_crl_file( 410 ctx->cred, 411 lt->lt_crlfile, 412 GNUTLS_X509_FMT_PEM ); 413 if ( rc < 0 ) return -1; 414 rc = 0; 415 } 416 417 /* FIXME: ITS#5992 - this should go be configurable, 418 * and V1 CA certs should be phased out ASAP. 419 */ 420 gnutls_certificate_set_verify_flags( ctx->cred, 421 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT ); 422 423 if ( is_server ) { 424 gnutls_dh_params_init(&ctx->dh_params); 425 gnutls_dh_params_generate2(ctx->dh_params, DH_BITS); 426 } 427 return 0; 428 } 429 430 static tls_session * 431 tlsg_session_new ( tls_ctx * ctx, int is_server ) 432 { 433 tlsg_ctx *c = (tlsg_ctx *)ctx; 434 tlsg_session *session; 435 436 session = ber_memcalloc ( 1, sizeof (*session) ); 437 if ( !session ) 438 return NULL; 439 440 session->ctx = c; 441 gnutls_init( &session->session, is_server ? GNUTLS_SERVER : GNUTLS_CLIENT ); 442 #ifdef HAVE_CIPHERSUITES 443 gnutls_priority_set( session->session, c->prios ); 444 #else 445 gnutls_set_default_priority( session->session ); 446 if ( c->kx_list ) { 447 gnutls_kx_set_priority( session->session, c->kx_list ); 448 gnutls_cipher_set_priority( session->session, c->cipher_list ); 449 gnutls_mac_set_priority( session->session, c->mac_list ); 450 } 451 #endif 452 if ( c->cred ) 453 gnutls_credentials_set( session->session, GNUTLS_CRD_CERTIFICATE, c->cred ); 454 455 if ( is_server ) { 456 int flag = 0; 457 if ( c->lo->ldo_tls_require_cert ) { 458 flag = GNUTLS_CERT_REQUEST; 459 if ( c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND || 460 c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) 461 flag = GNUTLS_CERT_REQUIRE; 462 gnutls_certificate_server_set_request( session->session, flag ); 463 } 464 } 465 return (tls_session *)session; 466 } 467 468 static int 469 tlsg_session_accept( tls_session *session ) 470 { 471 tlsg_session *s = (tlsg_session *)session; 472 int rc; 473 474 rc = gnutls_handshake( s->session ); 475 if ( rc == 0 && s->ctx->lo->ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER ) { 476 const gnutls_datum_t *peer_cert_list; 477 unsigned int list_size; 478 479 peer_cert_list = gnutls_certificate_get_peers( s->session, 480 &list_size ); 481 if ( !peer_cert_list && s->ctx->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_TRY ) 482 rc = 0; 483 else { 484 rc = tlsg_cert_verify( s ); 485 if ( rc && s->ctx->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_ALLOW ) 486 rc = 0; 487 } 488 } 489 return rc; 490 } 491 492 static int 493 tlsg_session_connect( LDAP *ld, tls_session *session ) 494 { 495 return tlsg_session_accept( session); 496 } 497 498 static int 499 tlsg_session_upflags( Sockbuf *sb, tls_session *session, int rc ) 500 { 501 tlsg_session *s = (tlsg_session *)session; 502 503 if ( rc != GNUTLS_E_INTERRUPTED && rc != GNUTLS_E_AGAIN ) 504 return 0; 505 506 switch (gnutls_record_get_direction (s->session)) { 507 case 0: 508 sb->sb_trans_needs_read = 1; 509 return 1; 510 case 1: 511 sb->sb_trans_needs_write = 1; 512 return 1; 513 } 514 return 0; 515 } 516 517 static char * 518 tlsg_session_errmsg( tls_session *sess, int rc, char *buf, size_t len ) 519 { 520 return (char *)gnutls_strerror( rc ); 521 } 522 523 static void 524 tlsg_x509_cert_dn( struct berval *cert, struct berval *dn, int get_subject ) 525 { 526 BerElementBuffer berbuf; 527 BerElement *ber = (BerElement *)&berbuf; 528 ber_tag_t tag; 529 ber_len_t len; 530 ber_int_t i; 531 532 ber_init2( ber, cert, LBER_USE_DER ); 533 tag = ber_skip_tag( ber, &len ); /* Sequence */ 534 tag = ber_skip_tag( ber, &len ); /* Sequence */ 535 tag = ber_peek_tag( ber, &len ); /* Context + Constructed (version) */ 536 if ( tag == 0xa0 ) { /* Version is optional */ 537 tag = ber_skip_tag( ber, &len ); 538 tag = ber_get_int( ber, &i ); /* Int: Version */ 539 } 540 tag = ber_skip_tag( ber, &len ); /* Int: Serial (can be longer than ber_int_t) */ 541 ber_skip_data( ber, len ); 542 tag = ber_skip_tag( ber, &len ); /* Sequence: Signature */ 543 ber_skip_data( ber, len ); 544 if ( !get_subject ) { 545 tag = ber_peek_tag( ber, &len ); /* Sequence: Issuer DN */ 546 } else { 547 tag = ber_skip_tag( ber, &len ); 548 ber_skip_data( ber, len ); 549 tag = ber_skip_tag( ber, &len ); /* Sequence: Validity */ 550 ber_skip_data( ber, len ); 551 tag = ber_peek_tag( ber, &len ); /* Sequence: Subject DN */ 552 } 553 len = ber_ptrlen( ber ); 554 dn->bv_val = cert->bv_val + len; 555 dn->bv_len = cert->bv_len - len; 556 } 557 558 static int 559 tlsg_session_my_dn( tls_session *session, struct berval *der_dn ) 560 { 561 tlsg_session *s = (tlsg_session *)session; 562 const gnutls_datum_t *x; 563 struct berval bv; 564 565 x = gnutls_certificate_get_ours( s->session ); 566 567 if (!x) return LDAP_INVALID_CREDENTIALS; 568 569 bv.bv_val = (char *) x->data; 570 bv.bv_len = x->size; 571 572 tlsg_x509_cert_dn( &bv, der_dn, 1 ); 573 return 0; 574 } 575 576 static int 577 tlsg_session_peer_dn( tls_session *session, struct berval *der_dn ) 578 { 579 tlsg_session *s = (tlsg_session *)session; 580 if ( !s->peer_der_dn.bv_val ) { 581 const gnutls_datum_t *peer_cert_list; 582 unsigned int list_size; 583 struct berval bv; 584 585 peer_cert_list = gnutls_certificate_get_peers( s->session, 586 &list_size ); 587 if ( !peer_cert_list ) return LDAP_INVALID_CREDENTIALS; 588 589 bv.bv_len = peer_cert_list->size; 590 bv.bv_val = (char *) peer_cert_list->data; 591 592 tlsg_x509_cert_dn( &bv, &s->peer_der_dn, 1 ); 593 } 594 *der_dn = s->peer_der_dn; 595 return 0; 596 } 597 598 /* what kind of hostname were we given? */ 599 #define IS_DNS 0 600 #define IS_IP4 1 601 #define IS_IP6 2 602 603 #define CN_OID "2.5.4.3" 604 605 static int 606 tlsg_session_chkhost( LDAP *ld, tls_session *session, const char *name_in ) 607 { 608 tlsg_session *s = (tlsg_session *)session; 609 int i, ret; 610 const gnutls_datum_t *peer_cert_list; 611 unsigned int list_size; 612 char altname[NI_MAXHOST]; 613 size_t altnamesize; 614 615 gnutls_x509_crt_t cert; 616 const char *name; 617 char *ptr; 618 char *domain = NULL; 619 #ifdef LDAP_PF_INET6 620 struct in6_addr addr; 621 #else 622 struct in_addr addr; 623 #endif 624 int len1 = 0, len2 = 0; 625 int ntype = IS_DNS; 626 627 if( ldap_int_hostname && 628 ( !name_in || !strcasecmp( name_in, "localhost" ) ) ) 629 { 630 name = ldap_int_hostname; 631 } else { 632 name = name_in; 633 } 634 635 peer_cert_list = gnutls_certificate_get_peers( s->session, 636 &list_size ); 637 if ( !peer_cert_list ) { 638 Debug( LDAP_DEBUG_ANY, 639 "TLS: unable to get peer certificate.\n", 640 0, 0, 0 ); 641 /* If this was a fatal condition, things would have 642 * aborted long before now. 643 */ 644 return LDAP_SUCCESS; 645 } 646 ret = gnutls_x509_crt_init( &cert ); 647 if ( ret < 0 ) 648 return LDAP_LOCAL_ERROR; 649 ret = gnutls_x509_crt_import( cert, peer_cert_list, GNUTLS_X509_FMT_DER ); 650 if ( ret ) { 651 gnutls_x509_crt_deinit( cert ); 652 return LDAP_LOCAL_ERROR; 653 } 654 655 #ifdef LDAP_PF_INET6 656 if (inet_pton(AF_INET6, name, &addr)) { 657 ntype = IS_IP6; 658 } else 659 #endif 660 if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) { 661 if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4; 662 } 663 664 if (ntype == IS_DNS) { 665 len1 = strlen(name); 666 domain = strchr(name, '.'); 667 if (domain) { 668 len2 = len1 - (domain-name); 669 } 670 } 671 672 for ( i=0, ret=0; ret >= 0; i++ ) { 673 altnamesize = sizeof(altname); 674 ret = gnutls_x509_crt_get_subject_alt_name( cert, i, 675 altname, &altnamesize, NULL ); 676 if ( ret < 0 ) break; 677 678 /* ignore empty */ 679 if ( altnamesize == 0 ) continue; 680 681 if ( ret == GNUTLS_SAN_DNSNAME ) { 682 if (ntype != IS_DNS) continue; 683 684 /* Is this an exact match? */ 685 if ((len1 == altnamesize) && !strncasecmp(name, altname, len1)) { 686 break; 687 } 688 689 /* Is this a wildcard match? */ 690 if (domain && (altname[0] == '*') && (altname[1] == '.') && 691 (len2 == altnamesize-1) && !strncasecmp(domain, &altname[1], len2)) 692 { 693 break; 694 } 695 } else if ( ret == GNUTLS_SAN_IPADDRESS ) { 696 if (ntype == IS_DNS) continue; 697 698 #ifdef LDAP_PF_INET6 699 if (ntype == IS_IP6 && altnamesize != sizeof(struct in6_addr)) { 700 continue; 701 } else 702 #endif 703 if (ntype == IS_IP4 && altnamesize != sizeof(struct in_addr)) { 704 continue; 705 } 706 if (!memcmp(altname, &addr, altnamesize)) { 707 break; 708 } 709 } 710 } 711 if ( ret >= 0 ) { 712 ret = LDAP_SUCCESS; 713 } else { 714 /* find the last CN */ 715 i=0; 716 do { 717 altnamesize = 0; 718 ret = gnutls_x509_crt_get_dn_by_oid( cert, CN_OID, 719 i, 1, altname, &altnamesize ); 720 if ( ret == GNUTLS_E_SHORT_MEMORY_BUFFER ) 721 i++; 722 else 723 break; 724 } while ( 1 ); 725 726 if ( i ) { 727 altnamesize = sizeof(altname); 728 ret = gnutls_x509_crt_get_dn_by_oid( cert, CN_OID, 729 i-1, 0, altname, &altnamesize ); 730 } 731 732 if ( ret < 0 ) { 733 Debug( LDAP_DEBUG_ANY, 734 "TLS: unable to get common name from peer certificate.\n", 735 0, 0, 0 ); 736 ret = LDAP_CONNECT_ERROR; 737 if ( ld->ld_error ) { 738 LDAP_FREE( ld->ld_error ); 739 } 740 ld->ld_error = LDAP_STRDUP( 741 _("TLS: unable to get CN from peer certificate")); 742 743 } else { 744 ret = LDAP_LOCAL_ERROR; 745 if ( !len1 ) len1 = strlen( name ); 746 if ( len1 == altnamesize && strncasecmp(name, altname, altnamesize) == 0 ) { 747 ret = LDAP_SUCCESS; 748 749 } else if (( altname[0] == '*' ) && ( altname[1] == '.' )) { 750 /* Is this a wildcard match? */ 751 if( domain && 752 (len2 == altnamesize-1) && !strncasecmp(domain, &altname[1], len2)) { 753 ret = LDAP_SUCCESS; 754 } 755 } 756 } 757 758 if( ret == LDAP_LOCAL_ERROR ) { 759 altname[altnamesize] = '\0'; 760 Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match " 761 "common name in certificate (%s).\n", 762 name, altname, 0 ); 763 ret = LDAP_CONNECT_ERROR; 764 if ( ld->ld_error ) { 765 LDAP_FREE( ld->ld_error ); 766 } 767 ld->ld_error = LDAP_STRDUP( 768 _("TLS: hostname does not match CN in peer certificate")); 769 } 770 } 771 gnutls_x509_crt_deinit( cert ); 772 return ret; 773 } 774 775 static int 776 tlsg_session_strength( tls_session *session ) 777 { 778 tlsg_session *s = (tlsg_session *)session; 779 gnutls_cipher_algorithm_t c; 780 781 c = gnutls_cipher_get( s->session ); 782 return gnutls_cipher_get_key_size( c ) * 8; 783 } 784 785 /* suites is a string of colon-separated cipher suite names. */ 786 static int 787 tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites ) 788 { 789 #ifdef HAVE_CIPHERSUITES 790 const char *err; 791 return gnutls_priority_init( &ctx->prios, suites, &err ); 792 #else 793 char *ptr, *end; 794 int i, j, len, num; 795 int *list, nkx = 0, ncipher = 0, nmac = 0; 796 int *kx, *cipher, *mac; 797 798 num = 0; 799 ptr = suites; 800 do { 801 end = strchr(ptr, ':'); 802 if ( end ) 803 len = end - ptr; 804 else 805 len = strlen(ptr); 806 for (i=0; i<tlsg_n_ciphers; i++) { 807 if ( !strncasecmp( tlsg_ciphers[i].name, ptr, len )) { 808 num++; 809 break; 810 } 811 } 812 if ( i == tlsg_n_ciphers ) { 813 /* unrecognized cipher suite */ 814 return -1; 815 } 816 ptr += len + 1; 817 } while (end); 818 819 /* Space for all 3 lists */ 820 list = LDAP_MALLOC( (num+1) * sizeof(int) * 3 ); 821 if ( !list ) 822 return -1; 823 kx = list; 824 cipher = kx+num+1; 825 mac = cipher+num+1; 826 827 ptr = suites; 828 do { 829 end = strchr(ptr, ':'); 830 if ( end ) 831 len = end - ptr; 832 else 833 len = strlen(ptr); 834 for (i=0; i<tlsg_n_ciphers; i++) { 835 /* For each cipher suite, insert its algorithms into 836 * their respective priority lists. Make sure they 837 * only appear once in each list. 838 */ 839 if ( !strncasecmp( tlsg_ciphers[i].name, ptr, len )) { 840 for (j=0; j<nkx; j++) 841 if ( kx[j] == tlsg_ciphers[i].kx ) 842 break; 843 if ( j == nkx ) 844 kx[nkx++] = tlsg_ciphers[i].kx; 845 for (j=0; j<ncipher; j++) 846 if ( cipher[j] == tlsg_ciphers[i].cipher ) 847 break; 848 if ( j == ncipher ) 849 cipher[ncipher++] = tlsg_ciphers[i].cipher; 850 for (j=0; j<nmac; j++) 851 if ( mac[j] == tlsg_ciphers[i].mac ) 852 break; 853 if ( j == nmac ) 854 mac[nmac++] = tlsg_ciphers[i].mac; 855 break; 856 } 857 } 858 ptr += len + 1; 859 } while (end); 860 kx[nkx] = 0; 861 cipher[ncipher] = 0; 862 mac[nmac] = 0; 863 ctx->kx_list = kx; 864 ctx->cipher_list = cipher; 865 ctx->mac_list = mac; 866 return 0; 867 #endif 868 } 869 870 /* 871 * TLS support for LBER Sockbufs 872 */ 873 874 struct tls_data { 875 tlsg_session *session; 876 Sockbuf_IO_Desc *sbiod; 877 }; 878 879 static ssize_t 880 tlsg_recv( gnutls_transport_ptr_t ptr, void *buf, size_t len ) 881 { 882 struct tls_data *p; 883 884 if ( buf == NULL || len <= 0 ) return 0; 885 886 p = (struct tls_data *)ptr; 887 888 if ( p == NULL || p->sbiod == NULL ) { 889 return 0; 890 } 891 892 return LBER_SBIOD_READ_NEXT( p->sbiod, buf, len ); 893 } 894 895 static ssize_t 896 tlsg_send( gnutls_transport_ptr_t ptr, const void *buf, size_t len ) 897 { 898 struct tls_data *p; 899 900 if ( buf == NULL || len <= 0 ) return 0; 901 902 p = (struct tls_data *)ptr; 903 904 if ( p == NULL || p->sbiod == NULL ) { 905 return 0; 906 } 907 908 return LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len ); 909 } 910 911 static int 912 tlsg_sb_setup( Sockbuf_IO_Desc *sbiod, void *arg ) 913 { 914 struct tls_data *p; 915 tlsg_session *session = arg; 916 917 assert( sbiod != NULL ); 918 919 p = LBER_MALLOC( sizeof( *p ) ); 920 if ( p == NULL ) { 921 return -1; 922 } 923 924 gnutls_transport_set_ptr( session->session, (gnutls_transport_ptr)p ); 925 gnutls_transport_set_pull_function( session->session, tlsg_recv ); 926 gnutls_transport_set_push_function( session->session, tlsg_send ); 927 p->session = session; 928 p->sbiod = sbiod; 929 sbiod->sbiod_pvt = p; 930 return 0; 931 } 932 933 static int 934 tlsg_sb_remove( Sockbuf_IO_Desc *sbiod ) 935 { 936 struct tls_data *p; 937 938 assert( sbiod != NULL ); 939 assert( sbiod->sbiod_pvt != NULL ); 940 941 p = (struct tls_data *)sbiod->sbiod_pvt; 942 gnutls_deinit ( p->session->session ); 943 LBER_FREE( p->session ); 944 LBER_FREE( sbiod->sbiod_pvt ); 945 sbiod->sbiod_pvt = NULL; 946 return 0; 947 } 948 949 static int 950 tlsg_sb_close( Sockbuf_IO_Desc *sbiod ) 951 { 952 struct tls_data *p; 953 954 assert( sbiod != NULL ); 955 assert( sbiod->sbiod_pvt != NULL ); 956 957 p = (struct tls_data *)sbiod->sbiod_pvt; 958 gnutls_bye ( p->session->session, GNUTLS_SHUT_WR ); 959 return 0; 960 } 961 962 static int 963 tlsg_sb_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) 964 { 965 struct tls_data *p; 966 967 assert( sbiod != NULL ); 968 assert( sbiod->sbiod_pvt != NULL ); 969 970 p = (struct tls_data *)sbiod->sbiod_pvt; 971 972 if ( opt == LBER_SB_OPT_GET_SSL ) { 973 *((tlsg_session **)arg) = p->session; 974 return 1; 975 976 } else if ( opt == LBER_SB_OPT_DATA_READY ) { 977 if( gnutls_record_check_pending( p->session->session ) > 0 ) { 978 return 1; 979 } 980 } 981 982 return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg ); 983 } 984 985 static ber_slen_t 986 tlsg_sb_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) 987 { 988 struct tls_data *p; 989 ber_slen_t ret; 990 991 assert( sbiod != NULL ); 992 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) ); 993 994 p = (struct tls_data *)sbiod->sbiod_pvt; 995 996 ret = gnutls_record_recv ( p->session->session, buf, len ); 997 switch (ret) { 998 case GNUTLS_E_INTERRUPTED: 999 case GNUTLS_E_AGAIN: 1000 sbiod->sbiod_sb->sb_trans_needs_read = 1; 1001 sock_errset(EWOULDBLOCK); 1002 ret = 0; 1003 break; 1004 case GNUTLS_E_REHANDSHAKE: 1005 for ( ret = gnutls_handshake ( p->session->session ); 1006 ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN; 1007 ret = gnutls_handshake ( p->session->session ) ); 1008 sbiod->sbiod_sb->sb_trans_needs_read = 1; 1009 ret = 0; 1010 break; 1011 default: 1012 sbiod->sbiod_sb->sb_trans_needs_read = 0; 1013 } 1014 return ret; 1015 } 1016 1017 static ber_slen_t 1018 tlsg_sb_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) 1019 { 1020 struct tls_data *p; 1021 ber_slen_t ret; 1022 1023 assert( sbiod != NULL ); 1024 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) ); 1025 1026 p = (struct tls_data *)sbiod->sbiod_pvt; 1027 1028 ret = gnutls_record_send ( p->session->session, (char *)buf, len ); 1029 1030 if ( ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN ) { 1031 sbiod->sbiod_sb->sb_trans_needs_write = 1; 1032 sock_errset(EWOULDBLOCK); 1033 ret = 0; 1034 } else { 1035 sbiod->sbiod_sb->sb_trans_needs_write = 0; 1036 } 1037 return ret; 1038 } 1039 1040 static Sockbuf_IO tlsg_sbio = 1041 { 1042 tlsg_sb_setup, /* sbi_setup */ 1043 tlsg_sb_remove, /* sbi_remove */ 1044 tlsg_sb_ctrl, /* sbi_ctrl */ 1045 tlsg_sb_read, /* sbi_read */ 1046 tlsg_sb_write, /* sbi_write */ 1047 tlsg_sb_close /* sbi_close */ 1048 }; 1049 1050 /* Certs are not automatically varified during the handshake */ 1051 static int 1052 tlsg_cert_verify( tlsg_session *ssl ) 1053 { 1054 unsigned int status = 0; 1055 int err; 1056 time_t now = time(0); 1057 time_t peertime; 1058 1059 err = gnutls_certificate_verify_peers2( ssl->session, &status ); 1060 if ( err < 0 ) { 1061 Debug( LDAP_DEBUG_ANY,"TLS: gnutls_certificate_verify_peers2 failed %d\n", 1062 err,0,0 ); 1063 return -1; 1064 } 1065 if ( status ) { 1066 Debug( LDAP_DEBUG_TRACE,"TLS: peer cert untrusted or revoked (0x%x)\n", 1067 status, 0,0 ); 1068 return -1; 1069 } 1070 peertime = gnutls_certificate_expiration_time_peers( ssl->session ); 1071 if ( peertime == (time_t) -1 ) { 1072 Debug( LDAP_DEBUG_ANY, "TLS: gnutls_certificate_expiration_time_peers failed\n", 1073 0, 0, 0 ); 1074 return -1; 1075 } 1076 if ( peertime < now ) { 1077 Debug( LDAP_DEBUG_ANY, "TLS: peer certificate is expired\n", 1078 0, 0, 0 ); 1079 return -1; 1080 } 1081 peertime = gnutls_certificate_activation_time_peers( ssl->session ); 1082 if ( peertime == (time_t) -1 ) { 1083 Debug( LDAP_DEBUG_ANY, "TLS: gnutls_certificate_activation_time_peers failed\n", 1084 0, 0, 0 ); 1085 return -1; 1086 } 1087 if ( peertime > now ) { 1088 Debug( LDAP_DEBUG_ANY, "TLS: peer certificate not yet active\n", 1089 0, 0, 0 ); 1090 return -1; 1091 } 1092 return 0; 1093 } 1094 1095 tls_impl ldap_int_tls_impl = { 1096 "GnuTLS", 1097 1098 tlsg_init, 1099 tlsg_destroy, 1100 1101 tlsg_ctx_new, 1102 tlsg_ctx_ref, 1103 tlsg_ctx_free, 1104 tlsg_ctx_init, 1105 1106 tlsg_session_new, 1107 tlsg_session_connect, 1108 tlsg_session_accept, 1109 tlsg_session_upflags, 1110 tlsg_session_errmsg, 1111 tlsg_session_my_dn, 1112 tlsg_session_peer_dn, 1113 tlsg_session_chkhost, 1114 tlsg_session_strength, 1115 1116 &tlsg_sbio, 1117 1118 #ifdef LDAP_R_COMPILE 1119 tlsg_thr_init, 1120 #else 1121 NULL, 1122 #endif 1123 1124 0 1125 }; 1126 1127 #endif /* HAVE_GNUTLS */ 1128