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