61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
static int UnimportObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
static SSL_CTX *CTX_Init(State *statePtr, int proto, char *key,
char *cert, char *CAdir, char *CAfile, char *ciphers,
char *DHparams);
static int TlsLibInit(void);
#define TLS_PROTO_SSL2 0x01
#define TLS_PROTO_SSL3 0x02
#define TLS_PROTO_TLS1 0x04
#define TLS_PROTO_TLS1_1 0x08
#define TLS_PROTO_TLS1_2 0x10
#define ENABLED(flag, mask) (((flag) & (mask)) == (mask))
|
|
|
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
static int UnimportObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
static SSL_CTX *CTX_Init(State *statePtr, int proto, char *key,
char *cert, char *CAdir, char *CAfile, char *ciphers,
char *DHparams);
static int TlsLibInit(int uninitialize);
#define TLS_PROTO_SSL2 0x01
#define TLS_PROTO_SSL3 0x02
#define TLS_PROTO_TLS1 0x04
#define TLS_PROTO_TLS1_1 0x08
#define TLS_PROTO_TLS1_2 0x10
#define ENABLED(flag, mask) (((flag) & (mask)) == (mask))
|
113
114
115
116
117
118
119
120
121
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
|
#include <openssl/crypto.h>
/*
* Threaded operation requires locking callbacks
* Based from /crypto/cryptlib.c of OpenSSL and NSOpenSSL.
*/
#ifndef CRYPTO_NUM_LOCKS
#define CRYPTO_NUM_LOCKS 128
#endif
static Tcl_Mutex locks[CRYPTO_NUM_LOCKS];
static Tcl_Mutex init_mx;
static void CryptoThreadLockCallback (int mode, int n, const char *file, int line);
static unsigned long CryptoThreadIdCallback (void);
static void
CryptoThreadLockCallback(int mode, int n, const char *file, int line)
{
if (mode & CRYPTO_LOCK) {
Tcl_MutexLock(&locks[n]);
} else {
Tcl_MutexUnlock(&locks[n]);
}
}
static unsigned long
CryptoThreadIdCallback(void)
{
return (unsigned long) Tcl_GetCurrentThread();
}
#endif /* OPENSSL_THREADS */
#endif /* TCL_THREADS */
/*
*-------------------------------------------------------------------
|
<
<
<
|
|
|
<
|
<
|
|
|
|
|
|
<
<
|
|
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
#include <openssl/crypto.h>
/*
* Threaded operation requires locking callbacks
* Based from /crypto/cryptlib.c of OpenSSL and NSOpenSSL.
*/
static Tcl_Mutex *locks = NULL;
static Tcl_Mutex init_mx;
static void CryptoThreadLockCallback(int mode, int n, const char *file, int line);
static unsigned long CryptoThreadIdCallback(void);
static void CryptoThreadLockCallback(int mode, int n, const char *file, int line) {
if (mode & CRYPTO_LOCK) {
Tcl_MutexLock(&locks[n]);
} else {
Tcl_MutexUnlock(&locks[n]);
}
}
static unsigned long CryptoThreadIdCallback(void) {
return (unsigned long) Tcl_GetCurrentThread();
}
#endif /* OPENSSL_THREADS */
#endif /* TCL_THREADS */
/*
*-------------------------------------------------------------------
|
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
|
#else
Tcl_PkgRequire(interp, "Tcl", "8.4", 0)
#endif
== NULL) {
return TCL_ERROR;
}
if (TlsLibInit() != TCL_OK) {
Tcl_AppendResult(interp, "could not initialize SSL library", NULL);
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "tls::ciphers", CiphersObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::handshake", HandshakeObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::import", ImportObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
|
|
|
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
|
#else
Tcl_PkgRequire(interp, "Tcl", "8.4", 0)
#endif
== NULL) {
return TCL_ERROR;
}
if (TlsLibInit(0) != TCL_OK) {
Tcl_AppendResult(interp, "could not initialize SSL library", NULL);
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "tls::ciphers", CiphersObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::handshake", HandshakeObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::import", ImportObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
|
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
|
* initilizes SSL library
*
* Result:
* none
*
*------------------------------------------------------*
*/
static int TlsLibInit(void) {
static int initialized = 0;
int status = TCL_OK;
if (initialized) {
dprintf("Called, but using cached value");
return(status);
}
dprintf("Called");
initialized = 1;
#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
size_t num_locks;
Tcl_MutexLock(&init_mx);
#endif
#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
/* should we consider allocating mutexes? */
num_locks = CRYPTO_num_locks();
if (num_locks > CRYPTO_NUM_LOCKS) {
status = TCL_ERROR;
goto done;
}
CRYPTO_set_locking_callback(CryptoThreadLockCallback);
CRYPTO_set_id_callback(CryptoThreadIdCallback);
#endif
if (SSL_library_init() != 1) {
status = TCL_ERROR;
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<
<
<
<
<
|
<
<
<
|
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
|
* initilizes SSL library
*
* Result:
* none
*
*------------------------------------------------------*
*/
static int TlsLibInit(int uninitialize) {
static int initialized = 0;
int status = TCL_OK;
#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
size_t num_locks;
#endif
if (uninitialize) {
if (!initialized) {
dprintf("Asked to uninitialize, but we are not initialized");
return(TCL_OK);
}
dprintf("Asked to uninitialize");
#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
Tcl_MutexLock(&init_mx);
CRYPTO_set_locking_callback(NULL);
CRYPTO_set_id_callback(NULL);
if (locks) {
free(locks);
locks = NULL;
}
#endif
initialized = 0;
#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
Tcl_MutexUnlock(&init_mx);
#endif
return(TCL_OK);
}
if (initialized) {
dprintf("Called, but using cached value");
return(status);
}
dprintf("Called");
initialized = 1;
#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
Tcl_MutexLock(&init_mx);
num_locks = CRYPTO_num_locks();
locks = malloc(sizeof(*locks) * num_locks);
CRYPTO_set_locking_callback(CryptoThreadLockCallback);
CRYPTO_set_id_callback(CryptoThreadIdCallback);
#endif
if (SSL_library_init() != 1) {
status = TCL_ERROR;
|