1/*
2 * Copyright (C) 1997-2000 Matt Newman <matt@novadigm.com>
3 *
4 * $Header: /cvsroot/tls/tls/tlsInt.h,v 1.15 2007/06/22 21:20:38 hobbs2 Exp $
5 *
6 * TLS (aka SSL) Channel - can be layered on any bi-directional
7 * Tcl_Channel (Note: Requires Trf Core Patch)
8 *
9 * This was built from scratch based upon observation of OpenSSL 0.9.2B
10 *
11 * Addition credit is due for Andreas Kupries (a.kupries@westend.com), for
12 * providing the Tcl_ReplaceChannel mechanism and working closely with me
13 * to enhance it to support full fileevent semantics.
14 *
15 * Also work done by the follow people provided the impetus to do this "right":-
16 *	tclSSL (Colin McCormack, Shared Technology)
17 *	SSLtcl (Peter Antman)
18 *
19 */
20#ifndef _TSLINT_H
21#define _TLSINT_H
22
23#include "tls.h"
24#include <errno.h>
25#include <string.h>
26
27#ifdef __WIN32__
28#define WIN32_LEAN_AND_MEAN
29#include <windows.h>
30#include <wincrypt.h> /* OpenSSL needs this on Windows */
31#endif
32
33/* Handle tcl8.3->tcl8.4 CONST changes */
34#ifndef CONST84
35#define CONST84
36#endif
37
38#ifdef NO_PATENTS
39#define NO_IDEA
40#define NO_RC2
41#define NO_RC4
42#define NO_RC5
43#define NO_RSA
44#define NO_SSL2
45#endif
46
47#ifdef BSAFE
48#include <ssl.h>
49#include <err.h>
50#include <rand.h>
51#else
52#include <openssl/ssl.h>
53#include <openssl/err.h>
54#include <openssl/rand.h>
55#endif
56
57#ifdef TCL_STORAGE_CLASS
58# undef TCL_STORAGE_CLASS
59#endif
60#ifdef BUILD_tls
61# define TCL_STORAGE_CLASS DLLEXPORT
62#else
63# define TCL_STORAGE_CLASS DLLIMPORT
64#endif
65
66#ifndef ECONNABORTED
67#define ECONNABORTED	130	/* Software caused connection abort */
68#endif
69#ifndef ECONNRESET
70#define ECONNRESET	131	/* Connection reset by peer */
71#endif
72
73#ifdef DEBUG
74#define dprintf fprintf
75#else
76#define dprintf if (0) fprintf
77#endif
78
79#define SSL_ERROR(ssl,err)	\
80    ((char*)ERR_reason_error_string((unsigned long)SSL_get_error((ssl),(err))))
81/*
82 * OpenSSL BIO Routines
83 */
84#define BIO_TYPE_TCL	(19|0x0400)
85
86/*
87 * Defines for State.flags
88 */
89#define TLS_TCL_ASYNC	(1<<0)	/* non-blocking mode */
90#define TLS_TCL_SERVER	(1<<1)	/* Server-Side */
91#define TLS_TCL_INIT	(1<<2)	/* Initializing connection */
92#define TLS_TCL_DEBUG	(1<<3)	/* Show debug tracing */
93#define TLS_TCL_CALLBACK	(1<<4)	/* In a callback, prevent update
94					 * looping problem. [Bug 1652380] */
95
96#define TLS_TCL_DELAY (5)
97
98/*
99 * This structure describes the per-instance state
100 * of an ssl channel.
101 *
102 * The SSL processing context is maintained here, in the ClientData
103 */
104typedef struct State {
105    Tcl_Channel self;	/* this socket channel */
106    Tcl_TimerToken timer;
107
108    int flags;		/* see State.flags above  */
109    int watchMask;	/* current WatchProc mask */
110    int mode;		/* current mode of parent channel */
111
112    Tcl_Interp *interp;	/* interpreter in which this resides */
113    Tcl_Obj *callback;	/* script called for tracing, verifying and errors */
114    Tcl_Obj *password;	/* script called for certificate password */
115
116    int vflags;		/* verify flags */
117    SSL *ssl;		/* Struct for SSL processing */
118    SSL_CTX *ctx;	/* SSL Context */
119    BIO *bio;		/* Struct for SSL processing */
120    BIO *p_bio;		/* Parent BIO (that is layered on Tcl_Channel) */
121
122    char *err;
123} State;
124
125/*
126 * The following definitions have to be usable for 8.2.0-8.3.1 and 8.3.2+.
127 * The differences between these versions:
128 *
129 * 8.0-8.1:	There is no support for these in TLS 1.4 (get 1.3).  This
130 *		was the version with the original patch.
131 *
132 * 8.2.0-	Changed semantics for Tcl_StackChannel (Tcl_ReplaceChannel).
133 * 8.3.1:	Check at runtime to switch the behaviour. The patch is part
134 *		of the core from now on.
135 *
136 * 8.3.2+:	Stacked channels rewritten for better behaviour in some
137 *		situations (closing). Some new API's, semantic changes.
138 *
139 * The following magic was adapted from Trf 2.1 (Kupries).
140 */
141
142#define TLS_CHANNEL_VERSION_1	0x1
143#define TLS_CHANNEL_VERSION_2	0x2
144extern int channelTypeVersion;
145
146#ifdef USE_TCL_STUBS
147#ifndef Tcl_StackChannel
148/*
149 * The core we are compiling against is not patched, so supply the
150 * necesssary definitions here by ourselves. The form chosen for
151 * the procedure macros (reservedXXX) will notify us if the core
152 * does not have these reserved locations anymore.
153 *
154 * !! Synchronize the procedure indices in their definitions with
155 *    the patch to tcl.decls, as they have to be the same.
156 */
157
158/* 281 */
159typedef Tcl_Channel (tls_StackChannel) _ANSI_ARGS_((Tcl_Interp* interp,
160						    Tcl_ChannelType* typePtr,
161						    ClientData instanceData,
162						    int mask,
163						    Tcl_Channel prevChan));
164/* 282 */
165typedef void (tls_UnstackChannel) _ANSI_ARGS_((Tcl_Interp* interp,
166					       Tcl_Channel chan));
167
168#define Tcl_StackChannel     ((tls_StackChannel*) tclStubsPtr->reserved281)
169#define Tcl_UnstackChannel ((tls_UnstackChannel*) tclStubsPtr->reserved282)
170
171#endif /* Tcl_StackChannel */
172
173#ifndef Tcl_GetStackedChannel
174/*
175 * Separate definition, available in 8.2, but not 8.1 and before !
176 */
177
178/* 283 */
179typedef Tcl_Channel (tls_GetStackedChannel) _ANSI_ARGS_((Tcl_Channel chan));
180
181#define Tcl_GetStackedChannel ((tls_GetStackedChannel*) tclStubsPtr->reserved283)
182
183#endif /* Tcl_GetStackedChannel */
184
185
186#ifndef TCL_CHANNEL_VERSION_2
187/*
188 * Core is older than 8.3.2.  Supply the missing definitions for
189 * the new API's in 8.3.2.
190 */
191#define EMULATE_CHANNEL_VERSION_2
192
193typedef struct TlsChannelTypeVersion_* TlsChannelTypeVersion;
194#define TCL_CHANNEL_VERSION_2	((TlsChannelTypeVersion) 0x2)
195
196typedef int (TlsDriverHandlerProc) _ANSI_ARGS_((ClientData instanceData,
197					int interestMask));
198/* 394 */
199typedef int (tls_ReadRaw)  _ANSI_ARGS_((Tcl_Channel chan, char *dst,
200					int bytesToRead));
201/* 395 */
202typedef int (tls_WriteRaw) _ANSI_ARGS_((Tcl_Channel chan, char *src,
203					int srcLen));
204/* 397 */
205typedef int (tls_GetTopChannel) _ANSI_ARGS_((Tcl_Channel chan));
206
207/*
208 * Generating code for accessing these parts of the stub table when
209 * compiling against a core older than 8.3.2 is a hassle because even
210 * the 'reservedXXX' fields of the structure are not defined yet. So
211 * we have to write up some macros hiding some very hackish pointer
212 * arithmetics to get at these fields. We assume that pointer to
213 * functions are always of the same size.
214 */
215
216#define STUB_BASE   ((char*)(&(tclStubsPtr->tcl_UtfNcasecmp))) /* field 370 */
217#define procPtrSize (sizeof (Tcl_DriverBlockModeProc *))
218#define IDX(n)      (((n)-370) * procPtrSize)
219#define SLOT(n)     (STUB_BASE + IDX(n))
220
221#define Tcl_ReadRaw		(*((tls_ReadRaw**)	(SLOT(394))))
222#define Tcl_WriteRaw		(*((tls_WriteRaw**)	(SLOT(395))))
223#define Tcl_GetTopChannel	(*((tls_GetTopChannel**)(SLOT(396))))
224
225/*
226 * Required, easy emulation.
227 */
228#define Tcl_ChannelGetOptionProc(chanDriver) ((chanDriver)->getOptionProc)
229
230#endif /* TCL_CHANNEL_VERSION_2 */
231
232#endif /* USE_TCL_STUBS */
233
234/*
235 * Forward declarations
236 */
237
238EXTERN Tcl_ChannelType *Tls_ChannelType _ANSI_ARGS_((void));
239EXTERN Tcl_Channel	Tls_GetParent _ANSI_ARGS_((State *statePtr));
240
241EXTERN Tcl_Obj*		Tls_NewX509Obj _ANSI_ARGS_ (( Tcl_Interp *interp, X509 *cert));
242EXTERN void		Tls_Error _ANSI_ARGS_ ((State *statePtr, char *msg));
243EXTERN void		Tls_Free _ANSI_ARGS_ ((char *blockPtr));
244EXTERN void		Tls_Clean _ANSI_ARGS_ ((State *statePtr));
245EXTERN int		Tls_WaitForConnect _ANSI_ARGS_(( State *statePtr,
246							int *errorCodePtr));
247
248EXTERN BIO_METHOD *	BIO_s_tcl _ANSI_ARGS_((void));
249EXTERN BIO *		BIO_new_tcl _ANSI_ARGS_((State* statePtr, int flags));
250
251#endif /* _TLSINT_H */
252