[squid-dev] [PATCH] initial GnuTLS support for encrypted server connections
rousskov at measurement-factory.com
Sun Feb 5 02:20:55 UTC 2017
On 02/04/2017 12:31 PM, Amos Jeffries wrote:
> On 3/02/2017 4:05 a.m., Alex Rousskov wrote:
>> On 02/01/2017 11:51 PM, Amos Jeffries wrote:
>>> Can we agree on this being a fundamental design in Squid:
>>> * all connections have an associated socket ID.
>> That assumption would be too limiting (and, AFAICT, unnecessary). For
>> example, SSL connections inside SSL connections (HTTPS proxy) do not
>> have a socket. The same will apply to SSL connections inside HTTP/2
>> sessions. And eventually QUIC.
> I know. However the curent Squid code does not support such things.
> Probably _because_ it was designed with the above as one of the assumptions.
You seem to be moving goalposts. There is no fundamental Squid design
principle that requires everything called "connection" (in some context)
to have an associated socket. Do socketless connections exist in the
code today? I am not sure, but there is nothing at the fundamental
design level that would prevent them from being supported.
Moreover, if it does not exist already, there are real and significant
pressures to add such support (various features associated with HTTPS
proxies, not to mention HTTP/2 and QUIC) _and_ existing code that can be
reused to add such support (e.g., BIO-centric code).
>>> * all _open_ connections are stored in fd_table. Indexed by the
>>> connections socket ID. If not that is a bug.
>> Again, this is oversimplifying too much: fd_table is for sockets, not
> This is why I emphasized _open_ connections. The connections without
> socket ID (FD number) are represented by Comm::Connection in 'closed'
> state (fd == -1).
> If there are other types of connection in the current codebase please
> point me at them.
When talking about "fundamental Squid design", we should not really care
about the "current code base" much. Compared to changing the fundamental
design, changing code base is easy and not worth worrying about at this
>>> Now a Question, and please answer carefully:
>>> Does the PeerConnector or the new() operator 'connect' the "SSL
>>> connection" ?
>> Which new() operator?
> SSL_new() - the one being called by Ssl::CreateClient() to produce its
> return object.
SSL_new() does not connect an SSL connection. It creates it.
>> To connect an SSL connection one has to call
>> SSL_connect() or equivalent.
> Um, the SSL_connect() function performs the TLS/SSL handshake protocol.
Successfully performing a handshake is what moves an SSL connection into
the "connected" state. As you know, lot's of things can happen to that
SSL connection during a handshake (and some even _before_ the handshake,
like deciding which ciphers to offer or which session to resume, if any).
> Note sentence 2 of the formal definition:
> A TLS session is an association between a client and a server.
> ==> Sessions are created by the handshake protocol. Sessions define a
> set of cryptographic security parameters that can be shared among
> multiple connections. Sessions are used to avoid the expensive
> negotiation of new security parameters for each connection.
I do not know why I should note that sentence or why we are now talking
about sessions. That sentence certainly does not contradict what I have
been saying all along. As the above paragraph explains, some SSL
connections participate in new session creation. Some SSL connections
reuse old sessions (that were created by/during other SSL connections).
>> If PeerConnector or your new() operator
>> call SSL_connect() (directly or indirectly) then they are trying to
>> change the state of an SSL connection to "connected".
> This again diverges from the RFC 5246 definition:
> A connection is a transport (in the OSI layering model definition)
> that provides a suitable type of service. For TLS, such
> connections are peer-to-peer relationships. The connections are
> transient. Every connection is associated with one session.
Where do you see the divergence? The above definition is talking about
the transport connection to carry TLS connection information. When I am
talking about Security::Connection, I am talking about the TLS
connection, not the underlying transport connection (which may take many
> The section 6.1 which introduces the phrase "TLS connection" as a
> concept is documenting the "TLS Record Protocol". It is very clear that
> abstract "TLS connection" does not exist until the TLS records are
That "does not exist" assertion does not make sense to me. As an
abstract thing, it can be defined to start to exist when the first
record starts "flowing" to the other TLS agent, or when the first record
starts being constructed in the agent memory, or when the memory for
that first record is first allocated, or etc., etc.
The exact moment of TLS connection birth would depend on the discussion
level. Are we talking TLS specs? Abstract TLS algorithms? A
general-purpose TLS library? Squid code? Something else?
And, more importantly, why are we even trying to determine the exact
moment when an _abstraction_ such as a TLS connection starts to exist?!
> At which point it refers the transport protocol stack
This is incorrect. The TLS connection has TLS-specific states/properties
(defined by the TLS protocol) and knows almost nothing about the
underlying transport (which the TLS protocol lives largely out of scope).
> The session is different:
Agreed. TLS session is not a TLS connection. Those are different
concepts. The third concept is the transport connection that a TLS
connection uses to exchange TLS session information (among other things).
>> Does that answer your question?
> Sadly no, but in a way yes. Earlier you grumbled about conflating "SSL
> session" with "SSL connection".
> The only conflation I am seeing is in the OpenSSL documentation. The
> spec does not define the term at all, and the closest equivalent is a
> phrase used to abbreviate the transport description - not anyting crypto
Sorry, you lost me here. Surely, RFC 5246 defines all three things: SSL
connection, SSL session, and transport connection. Or, if you think the
exact protocol letters are somehow important in this context, TLS
connection, TLS session, and transport connection.
> So far as I can tell both the existing v5/v4 code and my patches do
> match the definitions in the RFC 5246 for "session", "connection", and
> the fuzzy "TLS connection".
Sorry, but they do not. I am not sure _why_ you are trying so hard to
inject a TLS session where the standard terminology uses TLS connection
so it is difficult for me to keep finding new arguments, but here is one
more mapping that might help (or hurt, I do not really know):
* The C type which OpenSSL calls "SSL", together with various operations
on that type represents a TLS connection. We should call its
wrappers/manipulators/derivatives using Security::Connection root.
* The type which OpenSSL calls SSL_SESSION is a TLS session. We should
call its wrappers/manipulators/derivatives using Security::Session root.
* Transport issues are largely outside Security:: realm, but we should
continue to use the global ::Connection and other existing
socket-related names/terminology for transport connections. OpenSSL does
not have a specific transport connection type because OpenSSL supports
several different transport abstractions, from can-be-anything BIO to
good-old-socket integer descriptors.
And, as I have begged many times before, let's not add "State", "Data",
"Info" and similar suffixes to names. In the vast majority of cases,
they only confuse developers (aha, this is not a class but some kind of
C structure to store "state" or "data"!) and make names longer. The
state of object Foo is the object itself, not some other FooState object.
More information about the squid-dev