Check-in [333d833f31]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Moved BIO_ wrappers into the BIO source and added more debugging output
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:333d833f31297d2afcebe2cab1cc0e62cb00f4aa
User & Date: rkeene 2016-12-08 08:36:03
Context
2016-12-08
08:50
Added a consolidated check for pre-OpenSSL 1.1 API usage check-in: 66023e665f user: rkeene tags: trunk
08:36
Moved BIO_ wrappers into the BIO source and added more debugging output check-in: 333d833f31 user: rkeene tags: trunk
08:35
Updated protocol negotiation test to use newer versions of TLS since SSLv3 is becoming less supported check-in: 2de09464e0 user: rkeene tags: trunk
Changes

Changes to tls.c.

641
642
643
644
645
646
647

648


649
650
651
652

653
654
655
656
657
658
659
		"\": not a TLS channel", NULL);
	return TCL_ERROR;
    }
    statePtr = (State *)Tcl_GetChannelInstanceData(chan);

    if (!SSL_is_init_finished(statePtr->ssl)) {
	int err = 0;

	ret = Tls_WaitForConnect(statePtr, &err);


	if ((statePtr->flags & TLS_TCL_ASYNC) && err == EAGAIN) {
            dprintf("Async set and err = EAGAIN");
	    ret = 0;
	}

	if (ret < 0) {
	    CONST char *errStr = statePtr->err;
	    Tcl_ResetResult(interp);
	    Tcl_SetErrno(err);

	    if (!errStr || *errStr == 0) {
		errStr = Tcl_PosixError(interp);







>

>
>




>







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
		"\": not a TLS channel", NULL);
	return TCL_ERROR;
    }
    statePtr = (State *)Tcl_GetChannelInstanceData(chan);

    if (!SSL_is_init_finished(statePtr->ssl)) {
	int err = 0;
        dprintf("Calling Tls_WaitForConnect");
	ret = Tls_WaitForConnect(statePtr, &err);
        dprintf("Tls_WaitForConnect returned: %i", ret);

	if ((statePtr->flags & TLS_TCL_ASYNC) && err == EAGAIN) {
            dprintf("Async set and err = EAGAIN");
	    ret = 0;
	}

	if (ret < 0) {
	    CONST char *errStr = statePtr->err;
	    Tcl_ResetResult(interp);
	    Tcl_SetErrno(err);

	    if (!errStr || *errStr == 0) {
		errStr = Tcl_PosixError(interp);

Changes to tlsBIO.c.

2
3
4
5
6
7
8





















9
10
11
12
13
14
15
...
188
189
190
191
192
193
194

195
196
197
198
199
200
201
 * Copyright (C) 1997-2000 Matt Newman <matt@novadigm.com>
 *
 * Provides BIO layer to interface openssl to Tcl.
 */

#include "tlsInt.h"






















/*
 * Forward declarations
 */

static int BioWrite	_ANSI_ARGS_ ((BIO *h, CONST char *buf, int num));
static int BioRead	_ANSI_ARGS_ ((BIO *h, char *buf, int num));
static int BioPuts	_ANSI_ARGS_ ((BIO *h, CONST char *str));
................................................................................
    case BIO_CTRL_FLUSH:
	dprintf("BIO_CTRL_FLUSH");
	if (channelTypeVersion == TLS_CHANNEL_VERSION_2) {
	    ret = ((Tcl_WriteRaw(chan, "", 0) >= 0) ? 1 : -1);
	} else {
	    ret = ((Tcl_Flush(chan) == TCL_OK) ? 1 : -1);
	}

	break;
    default:
	ret = 0;
	break;
    }
    return(ret);
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
 * Copyright (C) 1997-2000 Matt Newman <matt@novadigm.com>
 *
 * Provides BIO layer to interface openssl to Tcl.
 */

#include "tlsInt.h"

#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define BIO_get_data(bio)                ((bio)->ptr)
#define BIO_get_init(bio)                ((bio)->init)
#define BIO_get_shutdown(bio)            ((bio)->shutdown)
#define BIO_set_data(bio, val)           (bio)->ptr = (val)
#define BIO_set_init(bio, val)           (bio)->init = (val)
#define BIO_set_shutdown(bio, val)       (bio)->shutdown = (val)

/* XXX: This assumes the variable being assigned to is BioMethods */
#define BIO_meth_new(type_, name_)       (BIO_METHOD *)Tcl_Alloc(sizeof(BIO_METHOD)); \
                                         memset(BioMethods, 0, sizeof(BIO_METHOD)); \
                                         BioMethods->type = type_; \
                                         BioMethods->name = name_;
#define BIO_meth_set_write(bio, val)     (bio)->bwrite = val;
#define BIO_meth_set_read(bio, val)      (bio)->bread = val;
#define BIO_meth_set_puts(bio, val)      (bio)->bputs = val;
#define BIO_meth_set_ctrl(bio, val)      (bio)->ctrl = val;
#define BIO_meth_set_create(bio, val)    (bio)->create = val;
#define BIO_meth_set_destroy(bio, val)   (bio)->destroy = val;
#endif

/*
 * Forward declarations
 */

static int BioWrite	_ANSI_ARGS_ ((BIO *h, CONST char *buf, int num));
static int BioRead	_ANSI_ARGS_ ((BIO *h, char *buf, int num));
static int BioPuts	_ANSI_ARGS_ ((BIO *h, CONST char *str));
................................................................................
    case BIO_CTRL_FLUSH:
	dprintf("BIO_CTRL_FLUSH");
	if (channelTypeVersion == TLS_CHANNEL_VERSION_2) {
	    ret = ((Tcl_WriteRaw(chan, "", 0) >= 0) ? 1 : -1);
	} else {
	    ret = ((Tcl_Flush(chan) == TCL_OK) ? 1 : -1);
	}
        dprintf("BIO_CTRL_FLUSH returning value %li", ret);
	break;
    default:
	ret = 0;
	break;
    }
    return(ret);
}

Changes to tlsIO.c.

339
340
341
342
343
344
345

346
347
348
349
350
351
352
...
433
434
435
436
437
438
439

440
441
442
443
444
445
446
...
737
738
739
740
741
742
743

744
745
746
747
748
749


750
751
752
753
754


755
756
757
758
759
760
761
...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958

959
960
961
962
963
964
965
       dprintf("Callback is running, reading 0 bytes");

       bytesRead = 0;
       goto input;
    }

    if (!SSL_is_init_finished(statePtr->ssl)) {

	bytesRead = Tls_WaitForConnect(statePtr, errorCodePtr);
	if (bytesRead <= 0) {
            dprintf("Got an error (bytesRead = %i)", bytesRead);

	    if (*errorCodePtr == ECONNRESET) {
                dprintf("Got connection reset");
		/* Soft EOF */
................................................................................
       /* don't process any bytes while verify callback is running */
       written = -1;
       *errorCodePtr = EAGAIN;
       goto output;
    }

    if (!SSL_is_init_finished(statePtr->ssl)) {

	written = Tls_WaitForConnect(statePtr, errorCodePtr);
	if (written <= 0) {
            dprintf("Tls_WaitForConnect returned %i (err = %i)", written, *errorCodePtr);

	    goto output;
	}
    }
................................................................................
	 */

	Tcl_DeleteTimerHandler(statePtr->timer);
	statePtr->timer = (Tcl_TimerToken) NULL;
    }

    if (statePtr->flags & TLS_TCL_CALLBACK) {

	return 0;
    }

    if (statePtr->flags & TLS_TCL_INIT
	    && !SSL_is_init_finished(statePtr->ssl)) {
	int errorCode = 0;


	if (Tls_WaitForConnect(statePtr, &errorCode) <= 0 && errorCode == EAGAIN) {
            dprintf("Async flag could be set (didn't check) and errorCode == EAGAIN");
	    return 0;
	}
    }



    return mask;
}
 
/*
 *------------------------------------------------------*
 *
................................................................................
		if (statePtr->flags & TLS_TCL_ASYNC) {
		    dprintf("E! ");
		    *errorCodePtr = EAGAIN;
		    return -1;
		} else {
		    continue;
		}
	    } else if (err == 0) {
                if (SSL_in_init(statePtr->ssl)) {
                    dprintf("SSL_in_init() is true");
                }

                if (Tcl_Eof(statePtr->self)) {
                    dprintf("Error = 0 and EOF is set");

                    if (rc != SSL_ERROR_SYSCALL) {
                        dprintf("Error from some reason other than our BIO, returning 0");
                        return 0;
                    }
                }
		dprintf("CR! ");

		*errorCodePtr = ECONNRESET;
		return -1;
	    }
	    if (statePtr->flags & TLS_TCL_SERVER) {
		err = SSL_get_verify_result(statePtr->ssl);
		if (err != X509_V_OK) {
		    Tls_Error(statePtr,







>







 







>







 







>



<
|

>
>

|



>
>







 







|













>







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
...
739
740
741
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
...
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
       dprintf("Callback is running, reading 0 bytes");

       bytesRead = 0;
       goto input;
    }

    if (!SSL_is_init_finished(statePtr->ssl)) {
        dprintf("Calling Tls_WaitForConnect");
	bytesRead = Tls_WaitForConnect(statePtr, errorCodePtr);
	if (bytesRead <= 0) {
            dprintf("Got an error (bytesRead = %i)", bytesRead);

	    if (*errorCodePtr == ECONNRESET) {
                dprintf("Got connection reset");
		/* Soft EOF */
................................................................................
       /* don't process any bytes while verify callback is running */
       written = -1;
       *errorCodePtr = EAGAIN;
       goto output;
    }

    if (!SSL_is_init_finished(statePtr->ssl)) {
        dprintf("Calling Tls_WaitForConnect");
	written = Tls_WaitForConnect(statePtr, errorCodePtr);
	if (written <= 0) {
            dprintf("Tls_WaitForConnect returned %i (err = %i)", written, *errorCodePtr);

	    goto output;
	}
    }
................................................................................
	 */

	Tcl_DeleteTimerHandler(statePtr->timer);
	statePtr->timer = (Tcl_TimerToken) NULL;
    }

    if (statePtr->flags & TLS_TCL_CALLBACK) {
        dprintf("Returning 0 due to callback");
	return 0;
    }


    if ((statePtr->flags & TLS_TCL_INIT) && !SSL_is_init_finished(statePtr->ssl)) {
	int errorCode = 0;

        dprintf("Calling Tls_WaitForConnect");
	if (Tls_WaitForConnect(statePtr, &errorCode) <= 0 && errorCode == EAGAIN) {
            dprintf("Async flag could be set (didn't check) and errorCode == EAGAIN:  Returning 0");
	    return 0;
	}
    }

    dprintf("Returning %i", mask);

    return mask;
}
 
/*
 *------------------------------------------------------*
 *
................................................................................
		if (statePtr->flags & TLS_TCL_ASYNC) {
		    dprintf("E! ");
		    *errorCodePtr = EAGAIN;
		    return -1;
		} else {
		    continue;
		}
	    } else if (err <= 0) {
                if (SSL_in_init(statePtr->ssl)) {
                    dprintf("SSL_in_init() is true");
                }

                if (Tcl_Eof(statePtr->self)) {
                    dprintf("Error = 0 and EOF is set");

                    if (rc != SSL_ERROR_SYSCALL) {
                        dprintf("Error from some reason other than our BIO, returning 0");
                        return 0;
                    }
                }
		dprintf("CR! ");
                statePtr->flags |= TLS_TCL_HANDSHAKE_FAILED;
		*errorCodePtr = ECONNRESET;
		return -1;
	    }
	    if (statePtr->flags & TLS_TCL_SERVER) {
		err = SSL_get_verify_result(statePtr->ssl);
		if (err != X509_V_OK) {
		    Tls_Error(statePtr,

Changes to tlsInt.h.

48
49
50
51
52
53
54

55
56
57
58
59
60
61
...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#include <ssl.h>
#include <err.h>
#include <rand.h>
#else
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>

#endif

#ifndef NO_TLS1_1
#  ifndef SSL_OP_NO_TLSv1_1
#    define NO_TLS1_1
#  endif
#endif
................................................................................
void		Tls_Free _ANSI_ARGS_ ((char *blockPtr));
void		Tls_Clean _ANSI_ARGS_ ((State *statePtr));
int		Tls_WaitForConnect _ANSI_ARGS_(( State *statePtr,
							int *errorCodePtr));

BIO *		BIO_new_tcl _ANSI_ARGS_((State* statePtr, int flags));

#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define BIO_get_data(bio)                ((bio)->ptr)
#define BIO_get_init(bio)                ((bio)->init)
#define BIO_get_shutdown(bio)            ((bio)->shutdown)
#define BIO_set_data(bio, val)           (bio)->ptr = (val)
#define BIO_set_init(bio, val)           (bio)->init = (val)
#define BIO_set_shutdown(bio, val)       (bio)->shutdown = (val)

/* XXX: This assumes the variable being assigned to is BioMethods */
#define BIO_meth_new(type_, name_)       (BIO_METHOD *)Tcl_Alloc(sizeof(BIO_METHOD)); \
                                         memset(BioMethods, 0, sizeof(BIO_METHOD)); \
                                         BioMethods->type = type_; \
                                         BioMethods->name = name_;
#define BIO_meth_set_write(bio, val)     (bio)->bwrite = val;
#define BIO_meth_set_read(bio, val)      (bio)->bread = val;
#define BIO_meth_set_puts(bio, val)      (bio)->bputs = val;
#define BIO_meth_set_ctrl(bio, val)      (bio)->ctrl = val;
#define BIO_meth_set_create(bio, val)    (bio)->create = val;
#define BIO_meth_set_destroy(bio, val)   (bio)->destroy = val;
#endif

#endif /* _TLSINT_H */







>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
...
259
260
261
262
263
264
265





















266
#include <ssl.h>
#include <err.h>
#include <rand.h>
#else
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/opensslv.h>
#endif

#ifndef NO_TLS1_1
#  ifndef SSL_OP_NO_TLSv1_1
#    define NO_TLS1_1
#  endif
#endif
................................................................................
void		Tls_Free _ANSI_ARGS_ ((char *blockPtr));
void		Tls_Clean _ANSI_ARGS_ ((State *statePtr));
int		Tls_WaitForConnect _ANSI_ARGS_(( State *statePtr,
							int *errorCodePtr));

BIO *		BIO_new_tcl _ANSI_ARGS_((State* statePtr, int flags));






















#endif /* _TLSINT_H */