Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -42,11 +42,10 @@ */ #define F2N(key, dsp) \ (((key) == NULL) ? (char *)NULL : \ Tcl_TranslateFileName(interp, (key), (dsp))) -#define REASON() ERR_reason_error_string(ERR_get_error()) static void InfoCallback(const SSL *ssl, int where, int ret); static Tcl_ObjCmdProc CiphersObjCmd; static Tcl_ObjCmdProc HandshakeObjCmd; @@ -561,16 +560,16 @@ #endif default: break; } if (ctx == NULL) { - Tcl_AppendResult(interp, REASON(), (char *)NULL); + Tcl_AppendResult(interp, GET_ERR_REASON(), (char *)NULL); return TCL_ERROR; } ssl = SSL_new(ctx); if (ssl == NULL) { - Tcl_AppendResult(interp, REASON(), (char *)NULL); + Tcl_AppendResult(interp, GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return TCL_ERROR; } objPtr = Tcl_NewListObj( 0, NULL); @@ -926,11 +925,11 @@ */ statePtr->ssl = SSL_new(statePtr->ctx); if (!statePtr->ssl) { /* SSL library error */ - Tcl_AppendResult(interp, "couldn't construct ssl session: ", REASON(), (char *)NULL); + Tcl_AppendResult(interp, "couldn't construct ssl session: ", GET_ERR_REASON(), (char *)NULL); Tls_Free((void *)statePtr); return TCL_ERROR; } #ifndef OPENSSL_NO_TLSEXT @@ -1218,11 +1217,11 @@ SSL_CTX_set_tmp_dh(ctx, dh); 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: ", REASON(), (char *)NULL); + Tcl_AppendResult(interp, "Could not enable set DH auto: ", GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return NULL; } } } @@ -1236,20 +1235,20 @@ Tcl_DStringInit(&ds); if (SSL_CTX_use_certificate_file(ctx, F2N(certfile, &ds), SSL_FILETYPE_PEM) <= 0) { Tcl_DStringFree(&ds); Tcl_AppendResult(interp, "unable to set certificate file ", certfile, ": ", - REASON(), (char *)NULL); + GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return NULL; } } else if (cert != NULL) { load_private_key = 1; if (SSL_CTX_use_certificate_ASN1(ctx, cert_len, cert) <= 0) { Tcl_DStringFree(&ds); Tcl_AppendResult(interp, "unable to set certificate: ", - REASON(), (char *)NULL); + GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return NULL; } } else { certfile = (char*)X509_get_default_cert_file(); @@ -1256,11 +1255,11 @@ if (SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM) <= 0) { #if 0 Tcl_DStringFree(&ds); Tcl_AppendResult(interp, "unable to use default certificate file ", certfile, ": ", - REASON(), (char *)NULL); + GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return NULL; #endif } } @@ -1280,21 +1279,21 @@ if (SSL_CTX_use_PrivateKey_file(ctx, F2N(keyfile, &ds), SSL_FILETYPE_PEM) <= 0) { Tcl_DStringFree(&ds); /* flush the passphrase which might be left in the result */ Tcl_SetResult(interp, NULL, TCL_STATIC); Tcl_AppendResult(interp, "unable to set public key file ", keyfile, " ", - REASON(), (char *)NULL); + GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return NULL; } Tcl_DStringFree(&ds); } else if (key != NULL) { if (SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, ctx, key,key_len) <= 0) { Tcl_DStringFree(&ds); /* flush the passphrase which might be left in the result */ Tcl_SetResult(interp, NULL, TCL_STATIC); - Tcl_AppendResult(interp, "unable to set public key: ", REASON(), (char *)NULL); + Tcl_AppendResult(interp, "unable to set public key: ", GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return NULL; } } /* Now we know that a key and cert have been set against @@ -1316,11 +1315,11 @@ #if 0 Tcl_DStringFree(&ds); Tcl_DStringFree(&ds1); /* Don't currently care if this fails */ Tcl_AppendResult(interp, "SSL default verify paths: ", - REASON(), (char *)NULL); + GET_ERR_REASON(), (char *)NULL); SSL_CTX_free(ctx); return NULL; #endif } Index: generic/tlsInt.h ================================================================== --- generic/tlsInt.h +++ generic/tlsInt.h @@ -98,10 +98,38 @@ #define dprintBuffer(bufferName, bufferLength) /**/ #define dprintFlags(statePtr) /**/ #endif #define TCLTLS_SSL_ERROR(ssl,err) ((char*)ERR_reason_error_string((unsigned long)SSL_get_error((ssl),(err)))) +#define GET_ERR_REASON() ERR_reason_error_string(ERR_get_error()) + +/* Common list append macros */ +#define LAPPEND_BARRAY(interp, obj, text, value, size) {\ + if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \ + Tcl_ListObjAppendElement(interp, obj, Tcl_NewByteArrayObj(value, size)); \ +} +#define LAPPEND_STR(interp, obj, text, value, size) {\ + if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \ + Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(value, size)); \ +} +#define LAPPEND_INT(interp, obj, text, value) {\ + if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \ + Tcl_ListObjAppendElement(interp, obj, Tcl_NewIntObj(value)); \ +} +#define LAPPEND_LONG(interp, obj, text, value) {\ + if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \ + Tcl_ListObjAppendElement(interp, obj, Tcl_NewLongObj(value)); \ +} +#define LAPPEND_BOOL(interp, obj, text, value) {\ + if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \ + Tcl_ListObjAppendElement(interp, obj, Tcl_NewBooleanObj(value)); \ +} +#define LAPPEND_OBJ(interp, obj, text, listObj) {\ + if (text != NULL) Tcl_ListObjAppendElement(interp, obj, Tcl_NewStringObj(text, -1)); \ + Tcl_ListObjAppendElement(interp, obj, listObj); \ +} + /* * OpenSSL BIO Routines */ #define BIO_TYPE_TCL (19|0x0400)