Re: [PATCH RFC 4/5] net/tls: Add support for PF_TLSH (a TLS handshake listener)

Chuck Lever III
2022-04-27T15:25:07Z

> On Apr 26, 2022, at 8:03 PM, Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Tue, 26 Apr 2022 17:58:39 +0200 Hannes Reinecke wrote:
>>
>> - Establishing sockets from userspace will cause issues during
>> reconnection, as then someone (aka the kernel) will have to inform
>> userspace that a new connection will need to be established.
>> (And that has to happen while the root filesystem is potentially
>> inaccessible, so you can't just call arbitrary commands here)
>> (Especially call_usermodehelper() is out of the game)
>
> Indeed, we may need _some_ form of a notification mechanism and that's
> okay. Can be a (more generic) socket, can be something based on existing
> network storage APIs (IDK what you have there).
>
> My thinking was that establishing the session in user space would be
> easiest. We wouldn't need all the special getsockopt()s which AFAIU
> work around part of the handshake being done in the kernel, and which,
> I hope we can agree, are not beautiful.

In the prototype, the new socket options on AF_TLSH sockets
include:

#define TLSH_PRIORITIES 1 /* Retrieve TLS priorities string */
#define TLSH_PEERID 2 /* Retrieve peer identity */
#define TLSH_HANDSHAKE_TYPE 3 /* Retrieve handshake type */
#define TLSH_X509_CERTIFICATE 4 /* Retrieve x.509 certificate */

PRIORITIES is the TLS priorities string that the GnuTLS library
uses to parametrize the handshake (which TLS versions, ciphers,
and so on).

PEERID is a keyring serial number for the key that contains the
a Pre-Shared Key (for PSK handshakes) or the private key (for
x.509 handshakes).

HANDSHAKE_TYPE is an integer that represents the type of handshake
being requested: ClientHello, ServerHello, Rekey, and so on. This
option enables the repertoire of handshake types to be expanded.

X509_CERTIFICATE is a keyring serial number for the key that
contains an x.509 certificate.

When each handshake is complete, the handshake agent instantiates
the IV into the passed-in socket using existing kTLS socket options
before it returns the endpoint to the kernel.

There is nothing in these options that indicates to the handshake
agent what upper layer protocol is going to be used inside the TLS
session.

----

The new AF_TLSH socket options are not there because the handshake
is split between the kernel and user space. They are there because
the initial requester is (eg, in the case of NFS) mount.nfs, another
user space program. mount.nfs has to package up an x.509 cert or
pre-shared key and place it on a keyring to make it available to
the handshake agent.

The basic issue is that the administrative interfaces that
parametrize the handshakes are quite distant from the in-kernel
consumers that make handshake requests.

----

Further, in order to support server side TLS handshakes in the
kernel, we really do have to pass a kernel-created socket up to
user space. NFSD (and maybe the NVMe target) use in-kernel listeners
to accept incoming connections. Each new endpoint is created in the
kernel.

So if you truly seek generality in this facility, the user
space componentry must work with passed-in sockets rather than
creating them in user space.

--
Chuck Lever