Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -425,12 +425,12 @@ * Tls_Error -- * * Calls callback with error message. * * Side effects: - * The err field of the currently operative State is set - * to a string describing the SSL negotiation failure reason + * The err field of the currently operative State is set to a + * string describing the SSL negotiation failure reason * *------------------------------------------------------------------- */ void Tls_Error( @@ -1769,11 +1769,11 @@ /* Verify is a stacked channel */ if (parent == NULL) { Tcl_AppendResult(interp, "bad channel \"", Tcl_GetChannelName(chan), "\": not a stacked channel", (char *)NULL); - Tcl_SetErrorCode(interp, "TLS", "UNIMPORT", "CHANNEL", "INVALID", (char *)NULL); + Tcl_SetErrorCode(interp, "TLS", "UNIMPORT", "CHANNEL", "INVALID", (char *)NULL); return TCL_ERROR; } /* Flush any pending data */ if (Tcl_OutputBuffered(chan) > 0 && Tcl_Flush(chan) != TCL_OK) { @@ -1873,32 +1873,32 @@ } /* Where the CA names go */ certNames = sk_X509_NAME_new_null(); if (!certNames) { - goto cleanup; + goto cleanup; } /* Attempt to load all certs from the PEM file */ while ((cert = PEM_read_bio_X509(bio, NULL, 0, NULL)) != NULL) { - if (X509_STORE_add_cert(store, cert) == 0) { - X509_free(cert); - ret = 0; - goto cleanup; - } - /* Copy name to stack before certificate gets freed */ + if (X509_STORE_add_cert(store, cert) == 0) { + X509_free(cert); + ret = 0; + goto cleanup; + } + /* Copy name to stack before certificate gets freed */ name = X509_get_subject_name(cert); - if (name) { - X509_NAME *name_copy = X509_NAME_dup(name); - if (!name_copy || !sk_X509_NAME_push(certNames, name_copy)) { - X509_free(cert); + if (name) { + X509_NAME *name_copy = X509_NAME_dup(name); + if (!name_copy || !sk_X509_NAME_push(certNames, name_copy)) { + X509_free(cert); ret = 0; - goto cleanup; - } - } - X509_free(cert); - ret ++; + goto cleanup; + } + } + X509_free(cert); + ret ++; } /* At least one cert was added so retain the store and CA list */ if (ret) { if (SSL_CTX_get_cert_store(ctx) == NULL) { @@ -2175,11 +2175,12 @@ DH_free(dh); } else { /* Use well known DH parameters that have built-in support in OpenSSL */ if (!SSL_CTX_set_dh_auto(ctx, 1)) { - Tcl_AppendResult(interp, "Could not enable set DH auto: ", GET_ERR_REASON(), (char *)NULL); + Tcl_AppendResult(interp, "Could not enable set DH auto: ", GET_ERR_REASON(), + (char *)NULL); SSL_CTX_free(ctx); return NULL; } } } @@ -2254,11 +2255,11 @@ } /* Now we know that a key and cert have been set against * the SSL context */ if (!SSL_CTX_check_private_key(ctx)) { Tcl_AppendResult(interp, "private key does not match the certificate public key", - (char *)NULL); + (char *)NULL); SSL_CTX_free(ctx); return NULL; } } @@ -2534,11 +2535,11 @@ /* Make sure to operate on the topmost channel */ chan = Tcl_GetTopChannel(chan); if (Tcl_GetChannelType(chan) != Tls_ChannelType()) { Tcl_AppendResult(interp, "bad channel \"", Tcl_GetChannelName(chan), - "\": not a TLS channel", (char *)NULL); + "\": not a TLS channel", (char *)NULL); Tcl_SetErrorCode(interp, "TLS", "CONNECTION", "CHANNEL", "INVALID", (char *)NULL); return TCL_ERROR; } objPtr = Tcl_NewListObj(0, NULL); @@ -3225,11 +3226,11 @@ } /* *------------------------------------------------------* * - * TlsLibInit -- + * TlsLibInit -- * * Initializes SSL library once per application * * Results: * A standard Tcl result @@ -3332,11 +3333,11 @@ } /* *------------------------------------------------------------------- * - * Tls_SafeInit -- + * Tls_SafeInit -- * * This is a package initialization procedure for safe interps. * * Results: * Same as of 'Tls_Init' Index: generic/tlsIO.c ================================================================== --- generic/tlsIO.c +++ generic/tlsIO.c @@ -9,12 +9,12 @@ * Additional credit is due for Andreas Kupries (a.kupries@westend.com), 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) + * tclSSL (Colin McCormack, Shared Technology) + * SSLtcl (Peter Antman) * */ /* tlsBIO.c tlsIO.c @@ -36,14 +36,14 @@ * This procedure is invoked by the generic IO level to set channel to * blocking or nonblocking mode. Called by the generic I/O layer whenever * the Tcl_SetChannelOption() function is used with option -blocking. * * Results: - * 0 if successful or POSIX error code if failed. + * 0 if successful or POSIX error code if failed. * * Side effects: - * Sets the device into blocking or nonblocking mode. + * Sets the device into blocking or nonblocking mode. * *----------------------------------------------------------------------------- */ static int TlsBlockModeProc(ClientData instanceData, int mode) { State *statePtr = (State *) instanceData; @@ -65,14 +65,14 @@ * type specific cleanup when a SSL socket based channel is closed. * Called by the generic I/O layer whenever the Tcl_Close() function is * used. * * Results: - * 0 if successful or POSIX error code if failed. + * 0 if successful or POSIX error code if failed. * * Side effects: - * Closes the socket of the channel. + * Closes the socket of the channel. * *----------------------------------------------------------------------------- */ static int TlsCloseProc(ClientData instanceData, Tcl_Interp *interp) { State *statePtr = (State *) instanceData; @@ -124,14 +124,14 @@ * * Perform connect (client) or accept (server) function. Also performs * equivalent of handshake function. * * Result: - * 0 if successful, -1 if failed. + * 1 if successful, 0 if wait for connect, and -1 if failed. * * Side effects: - * Issues SSL_accept or SSL_connect + * Issues SSL_accept or SSL_connect * *----------------------------------------------------------------------------- */ int Tls_WaitForConnect(State *statePtr, int *errorCodePtr, int handshakeFailureIsPermanent) { unsigned long backingError; @@ -143,11 +143,11 @@ dprintFlags(statePtr); /* Can also check SSL_is_init_finished(ssl) */ if (!(statePtr->flags & TLS_TCL_INIT)) { dprintf("Tls_WaitForConnect called on already initialized channel -- returning with immediate success"); - return 0; + return 1; } if (statePtr->flags & TLS_TCL_HANDSHAKE_FAILED) { /* * Different types of operations have different requirements @@ -198,10 +198,11 @@ dprintf("Got error: %s", ERR_reason_error_string(backingError)); } /* The retry flag is set by the BIO_set_retry_* functions */ bioShouldRetry = BIO_should_retry(statePtr->bio); + dprintf("bioShouldRetry = %d", bioShouldRetry); if (err <= 0) { if (rc == SSL_ERROR_WANT_CONNECT || rc == SSL_ERROR_WANT_ACCEPT) { bioShouldRetry = 1; } else if (rc == SSL_ERROR_WANT_READ) { @@ -221,12 +222,11 @@ dprintf("The I/O did not complete -- but we should try it again"); if (statePtr->flags & TLS_TCL_ASYNC) { dprintf("Returning EAGAIN so that it can be retried later"); *errorCodePtr = EAGAIN; - Tls_Error(statePtr, "Handshake not complete, will retry later"); - return -1; + return 0; } else { dprintf("Doing so now"); continue; } } @@ -242,10 +242,11 @@ *errorCodePtr = 0; break; case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ + /* This includes certificate validation errors */ dprintf("SSL_ERROR_SSL: Got permanent fatal SSL error, aborting immediately"); if (SSL_get_verify_result(statePtr->ssl) != X509_V_OK) { Tls_Error(statePtr, X509_verify_cert_error_string(SSL_get_verify_result(statePtr->ssl))); } if (backingError != 0) { @@ -295,50 +296,50 @@ case SSL_ERROR_WANT_READ: /* More data must be read from the underlying BIO layer in order to complete the actual SSL_*() operation. */ dprintf("SSL_ERROR_WANT_READ"); BIO_set_retry_read(statePtr->bio); *errorCodePtr = EAGAIN; - dprintf("ERR(%d, %d) ", rc, *errorCodePtr); + dprintf("ERR(SSL_ERROR_ZERO_RETURN, EAGAIN) "); statePtr->want |= TCL_READABLE; - return -1; + return 0; case SSL_ERROR_WANT_WRITE: /* There is data in the SSL buffer that must be written to the underlying BIO in order to complete the SSL_*() operation. */ dprintf("SSL_ERROR_WANT_WRITE"); BIO_set_retry_write(statePtr->bio); *errorCodePtr = EAGAIN; - dprintf("ERR(%d, %d) ", rc, *errorCodePtr); + dprintf("ERR(SSL_ERROR_WANT_WRITE, EAGAIN) "); statePtr->want |= TCL_WRITABLE; - return -1; + return 0; case SSL_ERROR_WANT_CONNECT: /* Connect would have blocked. */ dprintf("SSL_ERROR_WANT_CONNECT"); BIO_set_retry_special(statePtr->bio); BIO_set_retry_reason(statePtr->bio, BIO_RR_CONNECT); *errorCodePtr = EAGAIN; - dprintf("ERR(%d, %d) ", rc, *errorCodePtr); - return -1; + dprintf("ERR(SSL_ERROR_WANT_CONNECT, EAGAIN) "); + return 0; case SSL_ERROR_WANT_ACCEPT: /* Accept would have blocked */ dprintf("SSL_ERROR_WANT_ACCEPT"); BIO_set_retry_special(statePtr->bio); BIO_set_retry_reason(statePtr->bio, BIO_RR_ACCEPT); *errorCodePtr = EAGAIN; - dprintf("ERR(%d, %d) ", rc, *errorCodePtr); - return -1; + dprintf("ERR(SSL_ERROR_WANT_ACCEPT, EAGAIN) "); + return 0; case SSL_ERROR_WANT_X509_LOOKUP: /* App callback set by SSL_CTX_set_client_cert_cb has asked to be called again */ /* The operation did not complete because an application callback set by SSL_CTX_set_client_cert_cb() has asked to be called again. */ dprintf("SSL_ERROR_WANT_X509_LOOKUP"); BIO_set_retry_special(statePtr->bio); BIO_set_retry_reason(statePtr->bio, BIO_RR_SSL_X509_LOOKUP); *errorCodePtr = EAGAIN; - dprintf("ERR(%d, %d) ", rc, *errorCodePtr); - return -1; + dprintf("ERR(SSL_ERROR_WANT_X509_LOOKUP, EAGAIN) "); + return 0; case SSL_ERROR_WANT_ASYNC: /* Used with flag SSL_MODE_ASYNC, op didn't complete because an async engine is still processing data */ case SSL_ERROR_WANT_ASYNC_JOB: /* The asynchronous job could not be started because there were no async jobs available in the pool. */ @@ -348,23 +349,22 @@ case SSL_ERROR_WANT_RETRY_VERIFY: /* The operation did not complete because a certificate verification callback has asked to be called again via SSL_set_retry_verify(3). */ #endif default: /* The operation did not complete and should be retried later. */ - dprintf("Operation did not complete, call function again later: %i", rc); + dprintf("Operation did not complete, call function again later"); *errorCodePtr = EAGAIN; - dprintf("ERR(%d, %d) ", rc, *errorCodePtr); - Tls_Error(statePtr, "Operation did not complete, call function again later"); - return -1; + dprintf("ERR(Other, EAGAIN) "); + return 0; } dprintf("Removing the \"TLS_TCL_INIT\" flag since we have completed the handshake"); statePtr->flags &= ~TLS_TCL_INIT; - dprintf("Returning in success"); + dprintf("Returning success"); *errorCodePtr = 0; - return 0; + return 1; } /* *----------------------------------------------------------------------------- * @@ -377,11 +377,11 @@ * Results: * Returns the number of bytes read or -1 on error. Sets errorCodePtr to * a POSIX error code if an error occurred, or 0 if none. * * Side effects: - * Reads input from the input device of the channel. + * Reads input from the input device of the channel. * * Data is received in whole blocks known as records from the peer. A whole * record is processed (e.g. decrypted) in one go and is buffered by OpenSSL * until it is read by the application via a call to SSL_read. * @@ -409,11 +409,10 @@ dprintf("Calling Tls_WaitForConnect"); tlsConnect = Tls_WaitForConnect(statePtr, errorCodePtr, 0); if (tlsConnect < 0) { dprintf("Got an error waiting to connect (tlsConnect = %i, *errorCodePtr = %i)", tlsConnect, *errorCodePtr); - Tls_Error(statePtr, strerror(*errorCodePtr)); bytesRead = -1; if (*errorCodePtr == ECONNRESET) { dprintf("Got connection reset"); /* Soft EOF */ @@ -506,30 +505,27 @@ /* Op did not complete due to not enough data was available. Retry later. */ dprintf("Got SSL_ERROR_WANT_READ, mapping this to EAGAIN"); *errorCodePtr = EAGAIN; bytesRead = -1; statePtr->want |= TCL_READABLE; - Tls_Error(statePtr, "SSL_ERROR_WANT_READ"); BIO_set_retry_read(statePtr->bio); break; case SSL_ERROR_WANT_WRITE: /* Op did not complete due to unable to send all data to the BIO. Retry later. */ dprintf("Got SSL_ERROR_WANT_WRITE, mapping this to EAGAIN"); *errorCodePtr = EAGAIN; bytesRead = -1; statePtr->want |= TCL_WRITABLE; - Tls_Error(statePtr, "SSL_ERROR_WANT_WRITE"); BIO_set_retry_write(statePtr->bio); break; case SSL_ERROR_WANT_X509_LOOKUP: /* Op didn't complete since callback set by SSL_CTX_set_client_cert_cb() asked to be called again */ dprintf("Got SSL_ERROR_WANT_X509_LOOKUP, mapping it to EAGAIN"); *errorCodePtr = EAGAIN; bytesRead = -1; - Tls_Error(statePtr, "SSL_ERROR_WANT_X509_LOOKUP"); break; case SSL_ERROR_SYSCALL: /* Some non-recoverable, fatal I/O error occurred */ dprintf("SSL_ERROR_SYSCALL"); @@ -565,13 +561,12 @@ break; case SSL_ERROR_WANT_ASYNC: /* Used with flag SSL_MODE_ASYNC, op didn't complete because an async engine is still processing data */ dprintf("Got SSL_ERROR_WANT_ASYNC, mapping this to EAGAIN"); - bytesRead = -1; *errorCodePtr = EAGAIN; - Tls_Error(statePtr, "SSL_ERROR_WANT_ASYNC"); + bytesRead = -1; break; default: dprintf("Unknown error (err = %i), mapping to EOF", err); *errorCodePtr = 0; @@ -592,15 +587,15 @@ * This procedure is invoked by the generic I/O layer to write data to the * BIO whenever the the Tcl_Write(), Tcl_WriteChars, and Tcl_WriteObj * functions are used. Equivalent to SSL_write_ex and SSL_write. * * Results: - * Returns the number of bytes written or -1 on error. Sets errorCodePtr - * to a POSIX error code if an error occurred, or 0 if none. + * Returns the number of bytes written or -1 on error. Sets errorCodePtr + * to a POSIX error code if an error occurred, or 0 if none. * * Side effects: - * Writes output on the output device of the channel. + * Writes output on the output device of the channel. * *----------------------------------------------------------------------------- */ static int TlsOutputProc(ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr) { unsigned long backingError; @@ -627,11 +622,10 @@ dprintf("Calling Tls_WaitForConnect"); tlsConnect = Tls_WaitForConnect(statePtr, errorCodePtr, 1); if (tlsConnect < 0) { dprintf("Got an error waiting to connect (tlsConnect = %i, *errorCodePtr = %i)", tlsConnect, *errorCodePtr); - Tls_Error(statePtr, strerror(*errorCodePtr)); written = -1; if (*errorCodePtr == ECONNRESET) { dprintf("Got connection reset"); /* Soft EOF */ @@ -732,30 +726,27 @@ /* Op did not complete due to not enough data was available. Retry later. */ dprintf("Got SSL_ERROR_WANT_READ, mapping it to EAGAIN"); *errorCodePtr = EAGAIN; written = -1; statePtr->want |= TCL_READABLE; - Tls_Error(statePtr, "SSL_ERROR_WANT_READ"); BIO_set_retry_read(statePtr->bio); break; case SSL_ERROR_WANT_WRITE: /* Op did not complete due to unable to send all data to the BIO. Retry later. */ dprintf("Got SSL_ERROR_WANT_WRITE, mapping it to EAGAIN"); *errorCodePtr = EAGAIN; written = -1; statePtr->want |= TCL_WRITABLE; - Tls_Error(statePtr, "SSL_ERROR_WANT_WRITE"); BIO_set_retry_write(statePtr->bio); break; case SSL_ERROR_WANT_X509_LOOKUP: /* Op didn't complete since callback set by SSL_CTX_set_client_cert_cb() asked to be called again */ dprintf("Got SSL_ERROR_WANT_X509_LOOKUP, mapping it to EAGAIN"); *errorCodePtr = EAGAIN; written = -1; - Tls_Error(statePtr, "SSL_ERROR_WANT_X509_LOOKUP"); break; case SSL_ERROR_SYSCALL: /* Some non-recoverable, fatal I/O error occurred */ dprintf("SSL_ERROR_SYSCALL"); @@ -782,21 +773,20 @@ case SSL_ERROR_ZERO_RETURN: /* Peer has closed the connection by sending the close_notify alert. Can't read, but can write. */ /* Need to return an EOF, so channel is closed which will send an SSL_shutdown(). */ dprintf("Got SSL_ERROR_ZERO_RETURN, this means an EOF has been reached"); - written = 0; *errorCodePtr = 0; + written = 0; Tls_Error(statePtr, "Peer has closed the connection for writing by sending the close_notify alert"); break; case SSL_ERROR_WANT_ASYNC: /* Used with flag SSL_MODE_ASYNC, op didn't complete because an async engine is still processing data */ dprintf("Got SSL_ERROR_WANT_ASYNC, mapping this to EAGAIN"); *errorCodePtr = EAGAIN; written = -1; - Tls_Error(statePtr, "SSL_ERROR_WANT_ASYNC"); break; default: dprintf("unknown error: %d", err); Tls_Error(statePtr, "Unknown error"); @@ -810,14 +800,14 @@ /* *----------------------------------------------------------------------------- * * Tls_GetParent -- * - * Get parent channel for a stacked channel. + * Get parent channel for a stacked channel. * * Results: - * Tcl_Channel or NULL if none. + * Tcl_Channel or NULL if none. * *----------------------------------------------------------------------------- */ Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags) { dprintf("Requested to get parent of channel %p", statePtr->self); @@ -836,14 +826,14 @@ * * Sets an option to value for a SSL socket based channel. Called by the * generic I/O layer whenever the Tcl_SetChannelOption() function is used. * * Results: - * TCL_OK if successful or TCL_ERROR if failed. + * TCL_OK if successful or TCL_ERROR if failed. * * Side effects: - * Updates channel option to new value. + * Updates channel option to new value. * *----------------------------------------------------------------------------- */ static int TlsSetOptionProc(ClientData instanceData, /* Socket state. */ @@ -882,11 +872,11 @@ * Results: * A standard Tcl result. The value of the specified option or a list of * all options and their values is returned in the supplied DString. * * Side effects: - * None. + * None. * *------------------------------------------------------------------- */ static int TlsGetOptionProc(ClientData instanceData, /* Socket state. */ @@ -918,18 +908,18 @@ } /* *----------------------------------------------------------------------------- * - * TlsChannelHandlerTimer -- + * TlsChannelHandlerTimer -- * * Called by the notifier via a timer, to flush out data waiting in * channel buffers. called by the generic I/O layer whenever the * Tcl_GetChannelHandle() function is used. * * Results: - * None. + * None. * * Side effects: * Creates notification event. * *----------------------------------------------------------------------------- @@ -975,11 +965,11 @@ * channel. Called by the generic I/O layer whenever the user (or the * system) announces its (dis)interest in events on the channel. This is * called repeatedly. * * Results: - * None. + * None. * * Side effects: * Sets up the time-based notifier so that future events on the channel * will be seen by TCL. * @@ -1033,10 +1023,14 @@ /* Do we have any pending events */ pending = (statePtr->want || \ ((mask & TCL_READABLE) && ((Tcl_InputBuffered(statePtr->self) > 0) || (BIO_ctrl_pending(statePtr->bio) > 0))) || ((mask & TCL_WRITABLE) && ((Tcl_OutputBuffered(statePtr->self) > 0) || (BIO_ctrl_wpending(statePtr->bio) > 0)))); + dprintf("IO Want=%d, input buffer=%d, output buffer=%d, BIO pending=%zd, BIO wpending=%zd", \ + statePtr->want, Tcl_InputBuffered(statePtr->self), Tcl_OutputBuffered(statePtr->self), \ + BIO_ctrl_pending(statePtr->bio), BIO_ctrl_wpending(statePtr->bio)); + if (!(mask & TCL_READABLE) || pending == 0) { /* Remove timer, if any */ if (statePtr->timer != (Tcl_TimerToken) NULL) { dprintf("A timer was found, deleting it"); Tcl_DeleteTimerHandler(statePtr->timer); @@ -1059,14 +1053,14 @@ * * This procedure is invoked by the generic IO level to retrieve an OS * specific handle associated with the channel. Not used for transforms. * * Results: - * The appropriate Tcl_File handle or NULL if none. + * The appropriate Tcl_File handle or NULL if none. * * Side effects: - * None. + * None. * *----------------------------------------------------------------------------- */ static int TlsGetHandleProc(ClientData instanceData, /* Socket state. */ int direction, /* TCL_READABLE or TCL_WRITABLE */ @@ -1086,14 +1080,14 @@ * that an event has occurred on the underlying channel. It is used by stacked channel drivers that * wish to be notified of events that occur on the underlying (stacked) * channel. * * Results: - * Type of event or 0 if failed + * Type of event or 0 if failed * * Side effects: - * May process the incoming event by itself. + * May process the incoming event by itself. * *----------------------------------------------------------------------------- */ static int TlsNotifyProc(ClientData instanceData, /* Socket state. */ int mask) /* type of event that occurred: @@ -1122,13 +1116,17 @@ return 0; } /* If not initialized, do connect */ if (statePtr->flags & TLS_TCL_INIT) { + int tlsConnect; + dprintf("Calling Tls_WaitForConnect"); - if (Tls_WaitForConnect(statePtr, &errorCode, 1) < 0) { - Tls_Error(statePtr, strerror(errorCode)); + + tlsConnect = Tls_WaitForConnect(statePtr, &errorCode, 1); + if (tlsConnect < 1) { + dprintf("Got an error waiting to connect (tlsConnect = %i, *errorCodePtr = %i)", tlsConnect, errorCode); if (errorCode == EAGAIN) { dprintf("Async flag could be set (didn't check) and errorCode == EAGAIN: Returning failed"); return 0; } @@ -1156,11 +1154,11 @@ * * Results: * Tcl_ChannelType structure. * * Side effects: - * None. + * None. * *----------------------------------------------------------------------------- */ static const Tcl_ChannelType tlsChannelType = { "tls", /* Type name */ Index: generic/tlsInt.h ================================================================== --- generic/tlsInt.h +++ generic/tlsInt.h @@ -10,11 +10,10 @@ * 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__))) @@ -222,20 +221,20 @@ /* * Forward declarations */ const Tcl_ChannelType *Tls_ChannelType(void); -Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags); +Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags); -Tcl_Obj *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert, int all); +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); +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); +BIO *BIO_new_tcl(State* statePtr, int flags); int BIO_cleanup(); #define PTR2INT(x) ((int) ((intptr_t) (x))) #endif /* _TLSINT_H */