#5690 defect new
The invoker of callRemote(t.p.amp.StartTLS) should always be a TLS client () and the responder should always be a TLS server
|Reported by:||habnabit||Owned by:||habnabit|
Description (last modified by )
Currently, if callRemote(StartTLS) is called on the TCP server side of an AMP connection, the TLS negotiation will be initiated in the wrong direction: the server thinks that it's responding to a handshake from a client, due to the fact that the TLS layer will "helpfully" call
set_connect_state based on the private, internal state that Twisted maintains about whether this is a client or server connection.
This means the handshake will fail if the TLS handshake bytes the server send arrives at the client in the same packet as some boxes - which it will, of course, because
callRemote(StartTLS) also sends a box. This usually produces an incomprehensible error message about some length limit being exceeded, since the AMP parser attempts to read some not-AMP bytes.
transport.startTLS() doesn't have quite enough information to do this the right way - it doesn't know whether you're calling
startTLS to begin or respond to a handshake - but this can be transparently handled by AMP, since if you're using
callRemote you are by definition the initiator.
(Note: the code which originally lead to this bug report was incorrect, and if you want this functionality, it's possible that you're doing it wrong too. Generally speaking, clients should always be the ones to initiate TLS; in particular, the way that clients and servers verify each others certificates, and what they do with the results of that verification, is very different. You really only want to call
callRemote(StartTLS) from the server if you are intentionally reversing the roles of client and server on the TCP connection.)
Change History (4)
comment:1 Changed 5 years ago by
|Summary:||t.p.amp.BinaryBoxProtocol doesn't stop parsing after startTLS → callRemote(t.p.amp.StartTLS) should always succeed for clients and servers|
comment:3 Changed 5 years ago by
|Summary:||callRemote(t.p.amp.StartTLS) should always succeed for clients and servers → The invoker of callRemote(t.p.amp.StartTLS) should always be a TLS client () and the responder should always be a TLS server|