1
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
/*
* Copyright (C) 1997-2000 Matt Newman <matt@novadigm.com>
*
* TLS (aka SSL) Channel - can be layered on any bi-directional
* Tcl_Channel (Note: Requires Trf Core Patch)
*
* This was built from scratch based upon observation of OpenSSL 0.9.2B
*
* Addition credit is due for Andreas Kupries ([email protected]), for
* providing the Tcl_ReplaceChannel mechanism and working closely with me
* to enhance it to support full fileevent semantics.
*
* Also work done by the follow people provided the impetus to do this "right":-
* tclSSL (Colin McCormack, Shared Technology)
* SSLtcl (Peter Antman)
*
*/
#ifndef _TLSINT_H
#define _TLSINT_H
#include "tls.h"
#include <errno.h>
#include <string.h>
#include <stdint.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wincrypt.h> /* OpenSSL needs this on Windows */
#endif
/* Handle TCL 8.6 CONST changes */
#ifndef CONST86
# if TCL_MAJOR_VERSION > 8
# define CONST86 const
# else
# define CONST86
# endif
#endif
/*
* Backwards compatibility for size type change
*/
#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7
#ifndef Tcl_Size
typedef int Tcl_Size;
#endif
#define TCL_SIZE_MODIFIER ""
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/opensslv.h>
#ifndef ECONNABORTED
#define ECONNABORTED 130 /* Software caused connection abort */
#endif
#ifndef ECONNRESET
#define ECONNRESET 131 /* Connection reset by peer */
#endif
#ifdef TCLEXT_TCLTLS_DEBUG
#include <ctype.h>
#define dprintf(...) { \
char dprintfBuffer[8192], *dprintfBuffer_p; \
dprintfBuffer_p = &dprintfBuffer[0]; \
dprintfBuffer_p += sprintf(dprintfBuffer_p, "%s:%i:%s():", __FILE__, __LINE__, __func__); \
dprintfBuffer_p += sprintf(dprintfBuffer_p, __VA_ARGS__); \
|
|
|
<
<
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
<
<
|
>
>
>
>
>
|
|
|
|
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
|
|
>
>
|
1
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/*
* Macro and structure definitions for TLS extension
*
* Copyright (C) 1997-2000 Matt Newman <matt@novadigm.com>
*
* Additional credit is due for Andreas Kupries ([email protected]), for
* providing the Tcl_ReplaceChannel mechanism and working closely with me
* to enhance it to support full fileevent semantics.
*
* Also work done by the follow people provided the impetus to do this "right":-
* tclSSL (Colin McCormack, Shared Technology)
* SSLtcl (Peter Antman)
*
*/
#ifndef _TLSINT_H
#define _TLSINT_H
/* Platform unique definitions */
#if ((defined(_WIN32)) || (defined(__MINGW32__)) || (defined(__MINGW64__)))
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <wincrypt.h> /* OpenSSL needs this on Windows */
#endif
#include "tls.h"
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/opensslv.h>
/* Windows needs to know which symbols to export. */
#ifdef BUILD_tls
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif /* BUILD_udp */
/* Handle TCL 8.6 CONST changes */
#ifndef CONST86
# if TCL_MAJOR_VERSION > 8
# define CONST86 const
# else
# define CONST86
# endif
#endif
/*
* Backwards compatibility for size type change
*/
#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7
#include <limits.h>
#ifndef TCL_SIZE_MAX
#define TCL_SIZE_MAX INT_MAX
#endif
#ifndef Tcl_Size
typedef int Tcl_Size;
#endif
#define TCL_SIZE_MODIFIER ""
#define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj
#define Tcl_NewSizeIntObj Tcl_NewIntObj
#define Tcl_NewSizeIntFromObj Tcl_NewWideIntObj
#endif
#ifndef JOIN
# define JOIN(a,b) JOIN1(a,b)
# define JOIN1(a,b) a##b
#endif
#ifndef TCL_UNUSED
# if defined(__cplusplus)
# define TCL_UNUSED(T) T
# elif defined(__GNUC__) && (__GNUC__ > 2)
# define TCL_UNUSED(T) T JOIN(dummy, __LINE__) __attribute__((unused))
# else
# define TCL_UNUSED(T) T JOIN(dummy, __LINE__)
# endif
#endif
/* Define missing POSIX error codes */
#ifndef ECONNABORTED
#define ECONNABORTED 130 /* Software caused connection abort */
#endif
#ifndef ECONNRESET
#define ECONNRESET 131 /* Connection reset by peer */
#endif
/* Debug and error macros */
#ifdef TCLEXT_TCLTLS_DEBUG
#include <ctype.h>
#define dprintf(...) { \
char dprintfBuffer[8192], *dprintfBuffer_p; \
dprintfBuffer_p = &dprintfBuffer[0]; \
dprintfBuffer_p += sprintf(dprintfBuffer_p, "%s:%i:%s():", __FILE__, __LINE__, __func__); \
dprintfBuffer_p += sprintf(dprintfBuffer_p, __VA_ARGS__); \
|
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \
Tcl_ListObjAppendElement(interp, obj, Tcl_NewLongObj(value)); \
}
#define LAPPEND_BOOL(interp, obj, text, value) {\
if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \
Tcl_ListObjAppendElement(interp, obj, Tcl_NewBooleanObj(value)); \
}
#define LAPPEND_OBJ(interp, obj, text, listObj) {\
if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \
Tcl_ListObjAppendElement(interp, obj, listObj); \
}
/*
* OpenSSL BIO Routines
*/
#define BIO_TYPE_TCL (19|0x0400)
/*
* Defines for State.flags
*/
#define TLS_TCL_ASYNC (1<<0) /* non-blocking mode */
#define TLS_TCL_SERVER (1<<1) /* Server-Side */
#define TLS_TCL_INIT (1<<2) /* Initializing connection */
#define TLS_TCL_DEBUG (1<<3) /* Show debug tracing */
#define TLS_TCL_CALLBACK (1<<4) /* In a callback, prevent update
* looping problem. [Bug 1652380] */
#define TLS_TCL_HANDSHAKE_FAILED (1<<5) /* Set on handshake failures and once set, all
* further I/O will result in ECONNABORTED errors. */
#define TLS_TCL_FASTPATH (1<<6) /* The parent channel is being used directly by the SSL library */
#define TLS_TCL_DELAY (5)
/*
* This structure describes the per-instance state of an SSL channel.
*
* The SSL processing context is maintained here, in the ClientData
*/
typedef struct State {
Tcl_Channel self; /* this socket channel */
Tcl_TimerToken timer;
int flags; /* see State.flags above */
int watchMask; /* current WatchProc mask */
int mode; /* current mode of parent channel */
Tcl_Interp *interp; /* interpreter in which this resides */
Tcl_Obj *callback; /* script called for tracing, info, and errors */
Tcl_Obj *password; /* script called for certificate password */
Tcl_Obj *vcmd; /* script called to verify or validate protocol config */
int vflags; /* verify flags */
SSL *ssl; /* Struct for SSL processing */
SSL_CTX *ctx; /* SSL Context */
BIO *bio; /* Struct for SSL processing */
BIO *p_bio; /* Parent BIO (that is layered on Tcl_Channel) */
unsigned char *protos; /* List of supported protocols in protocol format */
unsigned int protos_len; /* Length of protos */
char *err;
} State;
#ifdef USE_TCL_STUBS
#ifndef Tcl_StackChannel
#error "Unable to compile on this version of Tcl"
#endif /* Tcl_GetStackedChannel */
#endif /* USE_TCL_STUBS */
#if TCL_MAJOR_VERSION < 9
typedef char tls_free_type;
#else
typedef void tls_free_type;
#endif
/*
* Forward declarations
*/
const Tcl_ChannelType *Tls_ChannelType(void);
Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags);
Tcl_Obj *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert);
Tcl_Obj *Tls_NewCAObj(Tcl_Interp *interp, const SSL *ssl, int peer);
void Tls_Error(State *statePtr, char *msg);
void Tls_Free(tls_free_type *blockPtr);
void Tls_Clean(State *statePtr);
int Tls_WaitForConnect(State *statePtr, int *errorCodePtr, int handshakeFailureIsPermanent);
BIO *BIO_new_tcl(State* statePtr, int flags);
#define PTR2INT(x) ((int) ((intptr_t) (x)))
#endif /* _TLSINT_H */
|
|
|
<
<
<
<
<
|
>
<
>
|
|
|
>
|
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \
Tcl_ListObjAppendElement(interp, obj, Tcl_NewLongObj(value)); \
}
#define LAPPEND_BOOL(interp, obj, text, value) {\
if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \
Tcl_ListObjAppendElement(interp, obj, Tcl_NewBooleanObj(value)); \
}
#define LAPPEND_OBJ(interp, obj, text, tclObj) {\
if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \
Tcl_ListObjAppendElement(interp, obj, (tclObj != NULL) ? tclObj : Tcl_NewStringObj("", 0)); \
}
/*
* Defines for State.flags
*/
#define TLS_TCL_ASYNC (1<<0) /* non-blocking mode */
#define TLS_TCL_SERVER (1<<1) /* Server-Side */
#define TLS_TCL_INIT (1<<2) /* Initializing connection */
#define TLS_TCL_DEBUG (1<<3) /* Show debug tracing */
#define TLS_TCL_CALLBACK (1<<4) /* In a callback, prevent update
* looping problem. [Bug 1652380] */
#define TLS_TCL_HANDSHAKE_FAILED (1<<5) /* Set on handshake failures and once set, all
* further I/O will result in ECONNABORTED errors. */
#define TLS_TCL_FASTPATH (1<<6) /* The parent channel is being used directly by the SSL library */
#define TLS_TCL_DELAY (5)
/*
* This structure describes the per-instance state of an SSL channel.
*
* The SSL processing context is maintained here, in the ClientData
*/
typedef struct State {
Tcl_Channel self; /* this socket channel */
Tcl_TimerToken timer;
int flags; /* see State.flags above */
int watchMask; /* current WatchProc mask */
int want; /* pending wants from OpenSSL */
int mode; /* current mode of parent channel */
Tcl_Interp *interp; /* interpreter in which this resides */
Tcl_Obj *callback; /* script called for tracing, info, and errors */
Tcl_Obj *password; /* script called for certificate password */
Tcl_Obj *vcmd; /* script called to verify or validate protocol config */
int vflags; /* verify flags */
SSL *ssl; /* Struct for SSL processing */
SSL_CTX *ctx; /* SSL Context */
BIO *bio; /* Struct for SSL processing */
BIO *p_bio; /* Parent BIO (that is layered on Tcl_Channel) */
unsigned int protos_len; /* Length of protos */
unsigned char *protos; /* List of supported protocols in protocol format */
const char *err;
} State;
#ifdef USE_TCL_STUBS
#ifndef Tcl_StackChannel
#error "Unable to compile on this version of Tcl"
#endif /* Tcl_GetStackedChannel */
#endif /* USE_TCL_STUBS */
#if TCL_MAJOR_VERSION < 9
typedef char tls_free_type;
#else
typedef void tls_free_type;
#endif
/*
* Forward declarations
*/
const Tcl_ChannelType *Tls_ChannelType(void);
Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags);
Tcl_Obj *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert, int all);
Tcl_Obj *Tls_NewCAObj(Tcl_Interp *interp, const SSL *ssl, int peer);
void Tls_Error(State *statePtr, const char *msg);
void Tls_Free(tls_free_type *blockPtr);
void Tls_Clean(State *statePtr);
int Tls_WaitForConnect(State *statePtr, int *errorCodePtr, int handshakeFailureIsPermanent);
BIO *BIO_new_tcl(State* statePtr, int flags);
int BIO_cleanup();
#define PTR2INT(x) ((int) ((intptr_t) (x)))
#endif /* _TLSINT_H */
|