Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support "delayed encryption" via UCSPI-TLS #7

Open
schmonz opened this issue Nov 25, 2020 · 5 comments
Open

support "delayed encryption" via UCSPI-TLS #7

schmonz opened this issue Nov 25, 2020 · 5 comments

Comments

@schmonz
Copy link

schmonz commented Nov 25, 2020

Hi! Thank you for these UCSPI tools.

There's a longstanding UCSPI-compatible interface for application protocol clients and servers that want to start unencrypted and opportunistically upgrade to encrypted. It's called "UCSPI-TLS", it's a pretty simple interface like you'd expect in UCSPI-land, and I'm hoping you might implement it for tls{c,s}.

For example, an UCSPI-TLS-aware SMTP server could run under tlss -n, which would start an unencrypted session with three variables in the SMTP server's environment:

  1. SSLCTLFD, a control socket
  2. SSLREADFD, where to read from
  3. SSLWRITEFD, where to write to

When the SMTP server receives STARTTLS from a client, it would write a particular byte to ${SSLCTLFD} to have tlss initiate encryption. Then it would switch from fd 0 to ${SSLREADFD} and from fd 1 to ${SSLWRITEFD} for the remainder of the session.

That's pretty much it. Same thing for UCSPI clients running under tlsc -y, except they'd switch away from fds 6 and 7.

UCSPI-TLS is a very convenient interface to program for. I've used it for https://schmonz.com/qmail/acceptutils and @notqmail is considering it. One drawback for us, at the moment, is that for a long time there's only been one ready-to-run UCSPI-TLS implementation -- and there's only been sslserver -n, not sslclient -y, despite the original UCSPI-TLS patch having included both.

The ucspi-ssl maintainer has indicated intent to fix this oversight; an upcoming release of s6-networking will support UCSPI-TLS; and if your tools were to do likewise, users and system integrators would have their choice of three ways to satisfy an application's dependency on this interface. That'd make it much more comfortable for applications to decide to depend on UCSPI-TLS.

-n and -y aren't in the spec, I don't think, they just happen to be how the original authors implemented it (and the options appear available in your tools). Here's their implementation against an older ucspi-ssl, including patches for qmail to take advantage.

Thanks for your consideration!

@schmonz
Copy link
Author

schmonz commented Apr 6, 2021

Small update: s6-networking now includes UCSPI-TLS (see "Opportunistic TLS: s6-ucspitlsc and s6-ucspitlsd").

@schmonz
Copy link
Author

schmonz commented Oct 18, 2021

Update to the update: @skarnet has created smtpd-starttls-proxy, which isn't the smallest and clearest imaginable example of applying UCSPI-TLS -- because it has to be a proxy to do what it does -- but it's plenty small and clear, I think, to show how UCSPI-TLS support in your UCSPI tools could pay off in production systems.

@younix
Copy link
Owner

younix commented Nov 8, 2021

I prefer that the application executes tlsc(1) by itself like this example:
https://github.com/younix/sj/blob/master/sj.c#L289

I don't like the idea of an additional communication infrastructure in the whole USCPI design.

@schmonz
Copy link
Author

schmonz commented Nov 9, 2021

Pros and cons there, from where I sit. exec() is certainly simple to call (indeed, hard to get wrong) and that's always compelling, all other things being equal. But this approach sacrifices the usual UCSPI property that applications don't know or care which program is managing their sockets, which means an admin can't swap out one UCSPI socket provider for another without changing application code. (Unless we add some sort of custom runtime configurability to each application, which seems more internally consistent and more fully backwards.)

UCSPI-TLS changes the nature of an application's dependency on UCSPI -- the socket provider now must be one that's UCSPI-TLS aware -- but it preserves the direction of the dependency. UCSPI-TLS applications today work without code changes under any UCSPI-TLS-aware socket provider, exactly analogous to vanilla UCSPI.

There's a fair amount of consensus around UCSPI-TLS in the UCSPI ecosystem. It's been around for decades and has at least two independent publicly available implementations. If the design of UCSPI-TLS is horrendous, it might be advisable to ignore what other UCSPI implementations have chosen. If it's nowhere near horrendous, having your tools become a third independent UCSPI-TLS implementation would provide pleasant network effects (ha) to the robustness of the UCSPI ecosystem. That's the motivation behind my request.

You don't owe me anything here, of course! But I'd greatly appreciate your taking a look at what's involved in implementing UCSPI-TLS and deciding whether it's horrendous or actually kinda okay.

@schmonz
Copy link
Author

schmonz commented Nov 11, 2021

Since the topic came up on the qmail list today, here’s an example of something a real-world UCSPI application might want to do, enabled by UCSPI-TLS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants