Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -376,11 +376,11 @@ cmdPtr = Tcl_DuplicateObj(statePtr->vcmd); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj("verify", -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(Tcl_GetChannelName(statePtr->self), -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(depth)); - Tcl_ListObjAppendElement(interp, cmdPtr, Tls_NewX509Obj(interp, cert)); + Tcl_ListObjAppendElement(interp, cmdPtr, Tls_NewX509Obj(interp, cert, 0)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(ok)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj((char*)X509_verify_cert_error_string(err), -1)); /* Prevent I/O while callback is in progress */ @@ -2184,11 +2184,11 @@ } else { peer = SSL_get_certificate(statePtr->ssl); } /* Get X509 certificate info */ if (peer) { - objPtr = Tls_NewX509Obj(interp, peer); + objPtr = Tls_NewX509Obj(interp, peer, 1); if (objc == 2) { X509_free(peer); peer = NULL; } } else { Index: generic/tlsInt.h ================================================================== --- generic/tlsInt.h +++ generic/tlsInt.h @@ -211,11 +211,11 @@ * Forward declarations */ const Tcl_ChannelType *Tls_ChannelType(void); Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags); -Tcl_Obj *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert); +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); Index: generic/tlsX509.c ================================================================== --- generic/tlsX509.c +++ generic/tlsX509.c @@ -369,11 +369,11 @@ * *------------------------------------------------------* */ Tcl_Obj* -Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) { +Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert, int all) { Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL); BIO *bio = BIO_new(BIO_s_mem()); int mdnid, pknid, bits, len; unsigned int ulen; uint32_t xflags; @@ -594,20 +594,32 @@ string = X509_keyid_get0(cert, &len); LAPPEND_STR(interp, certPtr, "keyId", (char *) string, (Tcl_Size) len); } /* Certificate and dump all data */ - { - char certStr[CERT_STR_SIZE]; + if (all) { + Tcl_Obj *allObj = Tcl_NewByteArrayObj(NULL, 0); + Tcl_Obj *certObj = Tcl_NewByteArrayObj(NULL, 0); + unsigned char *allStr, *certStr; + + if (allObj == NULL || certObj == NULL) { + Tcl_DecrRefCount(allObj); + BIO_free(bio); + return certPtr; + } /* Get certificate */ + certStr = Tcl_SetByteArrayLength(certObj, CERT_STR_SIZE); len = BIO_to_Buffer(PEM_write_bio_X509(bio, cert), bio, certStr, CERT_STR_SIZE); - LAPPEND_STR(interp, certPtr, "certificate", certStr, (Tcl_Size) len); + Tcl_SetByteArrayLength(certObj, len); + LAPPEND_OBJ(interp, certPtr, "certificate", certObj) - /* Get all cert info */ - len = BIO_to_Buffer(X509_print_ex(bio, cert, flags, 0), bio, certStr, CERT_STR_SIZE); - LAPPEND_STR(interp, certPtr, "all", certStr, (Tcl_Size) len); + /* Get all info on certificate */ + allStr = Tcl_SetByteArrayLength(allObj, CERT_STR_SIZE * 2); + len = BIO_to_Buffer(X509_print_ex(bio, cert, flags, 0), bio, allStr, CERT_STR_SIZE * 2); + Tcl_SetByteArrayLength(allObj, len); + LAPPEND_OBJ(interp, certPtr, "all", allObj) } BIO_free(bio); return certPtr; }