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