Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -1199,19 +1199,23 @@ if (ret < 0 && ((statePtr->flags & TLS_TCL_ASYNC) && (err == EAGAIN))) { dprintf("Async set and err = EAGAIN"); ret = 0; } else if (ret < 0) { + long result; errStr = statePtr->err; Tcl_ResetResult(interp); Tcl_SetErrno(err); if (!errStr || (*errStr == 0)) { errStr = Tcl_PosixError(interp); } Tcl_AppendResult(interp, "handshake failed: ", errStr, (char *) NULL); + if ((result = SSL_get_verify_result(statePtr->ssl)) != X509_V_OK) { + Tcl_AppendResult(interp, " due to \"", X509_verify_cert_error_string(result), "\"", (char *) NULL); + } Tcl_SetErrorCode(interp, "TLS", "HANDSHAKE", "FAILED", (char *) NULL); dprintf("Returning TCL_ERROR with handshake failed: %s", errStr); return(TCL_ERROR); } else { if (err != 0) { Index: generic/tlsIO.c ================================================================== --- generic/tlsIO.c +++ generic/tlsIO.c @@ -164,11 +164,11 @@ rc = SSL_get_error(statePtr->ssl, err); backingError = ERR_get_error(); if (rc != SSL_ERROR_NONE) { dprintf("Got error: %i (rc = %i)", err, rc); - dprintf("Got error: %s", GET_ERR_REASON()); + dprintf("Got error: %s", ERR_reason_error_string(backingError)); } bioShouldRetry = 0; if (err <= 0) { if (rc == SSL_ERROR_WANT_CONNECT || rc == SSL_ERROR_WANT_ACCEPT || rc == SSL_ERROR_WANT_READ || rc == SSL_ERROR_WANT_WRITE) { @@ -188,10 +188,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); } else { dprintf("Doing so now"); continue; } @@ -228,15 +229,15 @@ dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); if (*errorCodePtr == ECONNRESET) { *errorCodePtr = ECONNABORTED; } - Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(Tcl_GetErrno())); + Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(*errorCodePtr)); } else { dprintf("I/O error occurred (backingError = %lu)", backingError); - *errorCodePtr = backingError; + *errorCodePtr = Tcl_GetErrno(); if (*errorCodePtr == ECONNRESET) { *errorCodePtr = ECONNABORTED; } Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } @@ -245,16 +246,16 @@ return(-1); case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ dprintf("SSL_ERROR_SSL: Got permanent fatal SSL error, aborting immediately"); + if (SSL_get_verify_result(statePtr->ssl) != X509_V_OK) { + Tls_Error(statePtr, (char *) X509_verify_cert_error_string(SSL_get_verify_result(statePtr->ssl))); + } if (backingError != 0) { Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } - if (SSL_get_verify_result(statePtr->ssl) != X509_V_OK) { - Tls_Error(statePtr, (char *) X509_verify_cert_error_string(SSL_get_verify_result(statePtr->ssl))); - } statePtr->flags |= TLS_TCL_HANDSHAKE_FAILED; *errorCodePtr = ECONNABORTED; return(-1); case SSL_ERROR_WANT_READ: @@ -367,10 +368,12 @@ case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ dprintf("SSL error, indicating that the connection has been aborted"); if (backingError != 0) { Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); + } else { + Tls_Error(statePtr, "Unknown SSL error"); } *errorCodePtr = ECONNABORTED; bytesRead = -1; #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -396,15 +399,15 @@ } else if (backingError == 0 && bytesRead == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; - Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(Tcl_GetErrno())); + Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(*errorCodePtr)); } else { dprintf("I/O error occurred (backingError = %lu)", backingError); - *errorCodePtr = backingError; + *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } break; @@ -424,16 +427,14 @@ default: dprintf("Unknown error (err = %i), mapping to EOF", err); *errorCodePtr = 0; bytesRead = 0; + Tls_Error(statePtr, "Unknown error"); break; } - if (*errorCodePtr < 0) { - Tls_Error(statePtr, strerror(*errorCodePtr)); - } dprintf("Input(%d) -> %d [%d]", bufSize, bytesRead, *errorCodePtr); return(bytesRead); } /* @@ -491,10 +492,11 @@ dprintf("zero-write"); err = BIO_flush(statePtr->bio); if (err <= 0) { dprintf("Flushing failed"); + Tls_Error(statePtr, "Flush failed"); *errorCodePtr = EIO; written = 0; return(-1); } @@ -564,15 +566,15 @@ } else if (backingError == 0 && written == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); written = -1; - Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(Tcl_GetErrno())); + Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(*errorCodePtr)); } else { dprintf("I/O error occurred (backingError = %lu)", backingError); - *errorCodePtr = backingError; + *errorCodePtr = Tcl_GetErrno(); written = -1; Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } break; @@ -579,23 +581,23 @@ case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ dprintf("SSL error, indicating that the connection has been aborted"); if (backingError != 0) { Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); + } else { + Tls_Error(statePtr, "Unknown SSL error"); } *errorCodePtr = ECONNABORTED; written = -1; break; default: dprintf("unknown error: %d", err); + Tls_Error(statePtr, "Unknown error"); break; } - if (*errorCodePtr < 0) { - Tls_Error(statePtr, strerror(*errorCodePtr)); - } dprintf("Output(%d) -> %d", toWrite, written); return(written); } /*