@@ -1780,11 +1780,10 @@ Tcl_Channel chan; char *channelName, *ciphers; int mode; const unsigned char *proto; unsigned int len; - char *peername = NULL; dprintf("Called"); switch (objc) { case 2: @@ -1834,15 +1833,12 @@ if (!peer && (ssl_certs == NULL || sk_X509_num(ssl_certs) == 0)) { return TCL_ERROR; } /* Peer name from cert */ - if (SSL_get_verify_result(statePtr->ssl) == X509_V_OK) { - peername = SSL_get0_peername(statePtr->ssl); - } Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("peername", -1)); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(peername, -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_get0_peername(statePtr->ssl), -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("sbits", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj(SSL_get_cipher_bits(statePtr->ssl, NULL))); ciphers = (char*)SSL_get_cipher(statePtr->ssl); @@ -1863,11 +1859,11 @@ /* Report the selected protocol as a result of the negotiation */ SSL_get0_alpn_selected(statePtr->ssl, &proto, &len); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int)len)); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("version", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("protocol", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_get_version(statePtr->ssl), -1)); Tcl_SetObjResult(interp, objPtr); return TCL_OK; clientData = clientData; @@ -1890,11 +1886,10 @@ Tcl_Obj *objPtr; const SSL *ssl; const SSL_CIPHER *cipher; const SSL_SESSION *session; const unsigned char *proto; - unsigned int len; long mode; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "channel"); return(TCL_ERROR); @@ -1920,11 +1915,11 @@ if (ssl != NULL) { /* connection state */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("state", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_state_string_long(ssl), -1)); - /* Get server name */ + /* Get SNI requested server name */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("servername", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name), -1)); /* Get protocol */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("protocol", -1)); @@ -1933,18 +1928,21 @@ /* Renegotiation allowed */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("renegotiation", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj( SSL_get_secure_renegotiation_support(ssl) ? "supported" : "not supported", -1)); - /* Report the selected protocol as a result of the ALPN negotiation */ - SSL_get0_alpn_selected(ssl, &proto, &len); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1)); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int)len)); - /* Get security level */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("securitylevel", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj(SSL_get_security_level(ssl))); + + /* Session info */ + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("session_reused", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewBooleanObj(SSL_session_reused(ssl))); + + /* Is server info */ + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("is_server", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewBooleanObj(SSL_is_server(ssl))); } /* Cipher info */ cipher = SSL_get_current_cipher(ssl); if (cipher != NULL) { @@ -1964,10 +1962,14 @@ /* alg_bits is actual key secret bits. If use bits and secret (algorithm) bits differ, the rest of the bits are fixed, i.e. for limited export ciphers (bits < 56) */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("min_version", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_CIPHER_get_version(cipher), -1)); + /* Get OpenSSL-specific ID, not IANA ID */ + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("id", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj((int) SSL_CIPHER_get_id(cipher))); + if (SSL_CIPHER_description(cipher, buf, sizeof(buf)) != NULL) { Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("description", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(buf, -1)); } } @@ -1975,25 +1977,22 @@ /* Session info */ session = SSL_get_session(ssl); if (session != NULL) { const unsigned char *ticket; size_t len2; + unsigned int ulen; const unsigned char *session_id; - - /* Session info */ - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("session_reused", -1)); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj(SSL_session_reused(ssl))); - - /* Session id */ - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("session_id", -1)); - session_id = SSL_SESSION_get_id(session, &len); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(session_id, (int)len)); - - /* Session ticket - client only */ - SSL_SESSION_get0_ticket(session, &ticket, &len2); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("session_ticket", -1)); - Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(ticket, (int) len2)); + char buffer[SSL_MAX_MASTER_KEY_LENGTH]; + + /* Report the selected protocol as a result of the ALPN negotiation */ + SSL_SESSION_get0_alpn_selected(session, &proto, &len); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) len)); + + /* Peer */ + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("peer", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_SESSION_get0_peer(session), -1)); /* Resumable session */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("resumable", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj(SSL_SESSION_is_resumable(session))); @@ -2002,10 +2001,34 @@ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewLongObj(SSL_SESSION_get_time(session))); /* Timeout value */ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("timeout", -1)); Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewLongObj(SSL_SESSION_get_timeout(session))); + + /* Lifetime hint */ + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("lifetime", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewLongObj(SSL_SESSION_get_ticket_lifetime_hint(session))); + + /* Session id */ + session_id = SSL_SESSION_get_id(session, &ulen); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("session_id", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewByteArrayObj(session_id, (int) ulen)); + + /* Session ticket - client only */ + SSL_SESSION_get0_ticket(session, &ticket, &len2); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("session_ticket", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewByteArrayObj(ticket, (int) len2)); + + /* Ticket app data */ + SSL_SESSION_get0_ticket_appdata(session, &ticket, &len2); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("ticket_app_data", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewByteArrayObj(ticket, (int) len2)); + + /* Get master key */ + len2 = SSL_SESSION_get_master_key(session, buffer, SSL_MAX_MASTER_KEY_LENGTH); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("master_key", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewByteArrayObj(buffer, (int) len2)); } /* Compression info */ if (ssl != NULL) { #ifdef HAVE_SSL_COMPRESSION