TLSPOOL_STARTTLS(3)
π TLSPOOL_STARTTLS π
ok so this is TLSPOOL_STARTTLS(3), straight out of the Library Calls section, and bestie it is a lot β but it's literally the main character of the whole TLS Pool so buckle up π
β¨ NAME β¨
tlspool_starttls β the glow-up where you take a plaintext connection and wrap it in TLS π₯
π SYNOPSIS π
#include <tlspool/commands.h>
#include <tlspool/starttls.h>
int tlspool_starttls (int cryptfd, starttls_t *tlsdata,
void *privdata,
int (*namedconnect) (starttls_t *tlsdata, void *privdata));
π¦ DESCRIPTION π¦
okay so tlspool_starttls() is the main facilitation function of the TLS Pool β it starts a TLS session under control of the TLS Pool. and like, when I say "under control" I mean the TLS Pool encapsulates all the concerns of security and honestly most of the ones that relate to privacy too?? the application that calls tlspool_starttls() talks to the TLS Pool in terms of local and remote identities, but not in terms of credentials like certificates, keys or passwords β and also not in terms of policy settings or any other mechanistic aspects of TLS. none of that is your problem anymore, it's giving delegation π
and no cap, it has been known that an application could implement TLS functionality in a matter of hours, with extreme examples of needing just half an hour of programming effort π the cause of this is that no concerns related to TLS itself are left in the hands of the application, which can therefore focus entirely on what it does best β implement application logic. slay.
aside from programming simplicity, there's also the benefit of separate control over security matters and application content matters, which parallels operational practice, both in terms of system administration and software update responsibilities. it's giving β¨separation of concernsβ¨
the cryptfd handle supplies the TLS connection that is assumed to have been setup. when tlspool_starttls() ends, either in success or failure, this handle will no longer be available to the caller β the responsibility of closing it is passed on to the function and/or the TLS Pool. so like. don't touch it after. it's not yours anymore π«Ά
the tlsdata structure will be copied into the command structure, and upon completion it will be copied back. you can use it to communicate flags, protocols and other parameters, including the most important settings β local and remote identifiers. see the socket protocol document for details.
the privdata handle is used in conjunction with the namedconnect() call; it is passed on to connect the latter to the context from which it was called and is not further acted upon by this function. the namedconnect() function is called when the identities have been exchanged, and established, in the TLS handshake. this is the point at which a connection to the plaintext side is needed, and a callback to namedconnect() is made to find a handle for it. the function is called with a version of the tlsdata that has been updated by the TLS Pool to hold the local and remote identities. the return value should be -1 on error, with errno set, or it should be a valid file handle that can be passed back to the TLS Pool to connect to.
when the namedconnect argument passed is NULL, default behaviour is triggered π this interprets the privdata handle as an (int *) holding a file descriptor. if its value is valid, that is >= 0, it will be returned directly; otherwise, a socketpair(2) is constructed, one of the sockets is stored in privdata for use by the caller and the other is returned as the connected file descriptor for use by the TLS Pool. this means that the privdata must be properly initialised for this use, with either -1 (to create a socketpair) or the TLS Pool's plaintext file descriptor endpoint. the file handle returned in privdata, if it is >= 0, should be closed by the caller, both in case of success and failure. yeah. both. don't forget π
πΈ the fields in tlsdata when you CALL it πΈ
flagsβ seePIOF_STARTTLS_xxxbelowlocalβ may hold locally defined bits (none at the present time)ipprotoβ one of the valuesIPPROTO_TCP,IPPROTO_UDPandIPPROTO_SCTPstreamidβ whenipprotois set toIPPROTO_SCTP, this is the stream identifier on which to apply the STARTTLS request. it is common for SCTP to negotiate TLS in the full-blown manner over stream 0, and then to derive keys for the other streams from the master key of that one stream. iykyk π«localidβ is the local identity string. this string may be empty if no value is known. when functioning as a TLS client, the TLS Pool will take thedisclose.dbandtlspool_localid_service(3)mechanisms into account to filter this string's disclosure to the TLS server, or to do things such as substitution of a pseudonym, alias, group or role. iconic.remoteidβ is the remote identity string. this string may be empty if no value is known. when functioning as a TLS client, this value is used as a key for thedisclose.dband/or thetlspool_localid_service(3)in determining whether to conceal thelocalidvalue to this remote.ctlkeyβ is the control key for later use withtlspool_ctlkey_detach(3)andtlspool_ctlkey_reattach(3). the value provided to thetlspool_starttls()call should be filled with random data, both to prevent guessing the value in a rogue process, and to minimise the chances of an error due to hitting upon an already known control key. random. not "hunter2". please π«serviceβ is the IANA-standardised service name, as also stored in theservices(5)database. this can be used by the TLS Pool in its efforts to isolate security mechanisms from applications, so it is valuable that it is set to a proper value.timeoutβ is the number of milliseconds that the TLS handshake process waits for traffic from the remote peer. the special value0means that the default timeout will be used; the special value~0is interpreted to mean that no timeout should be applied by the TLS Pool.
π the fields in tlsdata when it COMES BACK successfully π
flagsβ seePIOF_STARTTLS_xxxbelowlocalβ may hold locally defined bits (none at the present time)ipprotoβ would not have changed.streamidβ would not have changed.localidβ is the authenticated identity of the local TLS end point. this same identity is passed to the remote peer through a TLS mechanism, if the remote asked for it. the value may be empty if no local identity is available to the remote peer.
note that the precise choice of the TLS security mechanism is of no concern to the application that called tlspool_starttls() β any security concerns about mechanisms to use and not use are part of the policy interface to the TLS Pool, which is not linked to the application but to an administrative interface, namely a local database. not your circus, not your monkeys π
remoteidβ is the authenticated identity of the remote TLS end point. if no identity is known, or if it was not authenticated in a way that would not count as a TLS error, then this value may be set to the empty string.ctlkeyβ would not have changed.serviceβ would not have changed.timeoutβ would not have changed.
π the PIOF_STARTTLS_xxx flags π
various PIOF_STARTTLS_xxx flags are sent and received in the tlsdata structure. when sent to the TLS Pool, they may provide it some freedom; when it is still set in the response then this freedom has been exercised. other flags indicate additional requirements β when these are not met, an error will be raised. their meaning in the response is meaningless. yeah, meaningless. don't read into it π
the following flags are recognised by the TLS Pool:
PIOF_STARTTLS_LOCALROLE_CLIENT,PIOF_STARTTLS_LOCALROLE_SERVER,PIOF_STARTTLS_LOCALROLE_PEER,PIOF_STARTTLS_REMOTEROLE_CLIENT,PIOF_STARTTLS_REMOTEROLE_SERVERandPIOF_STARTTLS_REMOTEROLE_PEERβ define whether the local or remote should act as a client or as a server. this is the TLS relationship, and may or may not match the transport connection over which TLS runs.
each side may be setup to act as a peer, which means it will mirror the other side. when either side is setup as a peer, the TLS Pool will begin as a client, but employ a TLS extension that can ignore the ClientHello from one of the sides β this is not currently a part of TLS, but may be added later on, in support of peer-to-peer connections as drafted in draft-vanrein-tls-p2p. future vibes only π¦
at some point, the TLS transaction has an obvious client and server side, even in peer-to-peer connections, and a normal handshake commences. but the remote role helps to decide which forms of identity are acceptable, and when a remote peer effectively became a server it may still present a client credential, and the similar freedom may also be assumed by the local side, although the "right" kind of credential is preferred.
PIOF_STARTTLS_DTLSβ requests to setup DTLS instead of TLS.PIOF_STARTTLS_WITHOUT_SNIβ can be used for client-side STARTTLS as an indication that if theremoteidis present then its domain should not be passed over to the other side as a Server Name Indication. this is not a common structure for all protocols, but is sent by default because it is an indicative TLS option. note that it is useful forxxxxs:protocols, which immediately start TLS, but usually not needed for protocols that issue aSTARTTLScommand during a normal exchange. anyhow, this is application-determined. if theremoteidcontains auser@part, it is not sent as part of the SNI information, because that would violate the format. that is a missed opportunity though πPIOF_STARTTLS_IGNORE_CACHESβ requires the TLS Pool to perform the validation here and now. it will not accept cached results from recent encounters as sufficient proof that the remote peer has the acclaimed identity. this can be used at places in an interaction where the identity of the remote peer must be firmly established. note that bypassing the caches dramatically increases the amount of work for the TLS Pool, and should thus be used with care π«Ά note that the validation outcome may still be cached, for future use when the peer relation is more relaxed. so it's expensive but it's not wasted, ok?PIOF_STARTTLS_REQUEST_REMOTEIDβ means that the TLS Pool should not strictly require, but merely request a remote identity. this is useful if the remote peer is a client who may not have a certificate to authenticate with, and should still be able to access the service over TLS. it is also useful to permit anonymous TLS connections to remote clients or servers if both sides agree to that. consent-based anon, we love to see it β
β οΈ bestie, quick warning before the next flag: a bidirectionally unauthenticated TLS connection is not protected from man in the middle attacks π. Its encryption may protect against passive observers, but that's the whole tea. Also: the flag we were just on is overridden by PIOF_STARTTLS_IGNORE_REMOTEID.
PIOF_STARTTLS_IGNORE_REMOTEIDβ tells the TLS Pool it doesn't even need to bother requesting a remote identity at all. If one is provided anyway, it is not validated. This is useful when the local application cannot use the remote identity in any useful way. It is also useful to permit anonymous TLS connections to remote clients or servers if both sides agree to that. Note that a bidirectionally unauthenticated TLS connection is not protected from man in the middle attacks, although it does warrant against passive observers. This flag overridesPIOF_STARTTLS_REQUEST_REMOTEID.PIOF_STARTTLS_DETACHβ instructs the TLS Pool to detach the TLS session from the client connection over which it was set up. That means no more control commands can be sent in relation to the TLS session until a client connection issues a successfultlspool_control_reattach(). In many applications, this flag will be combined withPIOF_STARTTLS_FORK, which has an independent meaning:PIOF_STARTTLS_FORKapplies to the independent life of a TLS session that is run by the TLS Pool, andPIOF_STARTTLS_DETACHapplies to the ability to send control commands in relation to a TLS session. The TLS Pool also implements one relationship betweenPIOF_STARTTLS_FORKandPIOF_STARTTLS_DETACH: after aPIOF_STARTTLS_FORK, the close-down of the client that set up a connection will automatically cause aPIOF_STARTTLS_DETACHof those TLS sessions. When thetlspool_starttls()exchange starts, the value inctlkeyis stored for future reference; control can be regained from any TLS Pool client connection that presents thectlkeyintlspool_control_reattach(3). See also thetlspool_control_detach(3)function, which performs the action as a separate step.PIOF_STARTTLS_FORKβ instructs the TLS Pool that the TLS session should continue to run when the client connection over which it was set up closes. By default, TLS sessions are terminated when their requesting client disappears, for instance due to termination of the requesting program.PIOF_STARTTLS_FORKandPIOF_STARTTLS_DETACHare different concepts:PIOF_STARTTLS_FORKapplies to the independent life of a TLS session that is run by the TLS Pool, andPIOF_STARTTLS_DETACHapplies to the ability to send control commands in relation to a TLS session. Many applications will use the two combined. The TLS Pool also implements one relation: after aPIOF_STARTTLS_FORK, the close-down of the client that set up a connection will automatically cause aPIOF_STARTTLS_DETACHof those TLS sessions.PIOF_STARTTLS_DOMAIN_REPRESENTS_USERβ indicates that the remote identity need not be the expecteduser@domain, but that the domain is acceptable as well. This is a common flag on protocols such as SMTP, where a server represents all users under its domain, and authenticates as the domain instead of as the user. Note that the flag applies equally well to clients as it does to servers. If an application does not supply this flag, it must supply anyremote_idfield for a STARTTLS exchange in the exact format as it is supported by the server. The returnedremote_idwill always be the exact identity as provided by the server.PIOF_STARTTLS_RENEGOTIATEβ takes a previously agreed TLS connection and renegotiates identities as specified in this request'stlsdata. Thectlkeyfield indicates an attached TLS connection that is to be renegotiated; this field will not be modified in the course of this invocation of thetlspool_starttls()function.
π« RETURN VALUE π«
The function returns a file descriptor >= 0 on success π. If an error occurs, the function returns -1 and errno is set appropriately.
βοΈ AUTHOR βοΈ
Written by Rick van Rein of OpenFortress.nl, for the ARPA2.net project.
π REPORTING BUGS π
For any discussion, including about bugs, please use the mailing list found on http://lists.arpa2.org/mailman/listinfo/tls-pool.
Please read the software distribution's README, INSTALL and TODO files for information about the tlspool-daemon implementation status.
Β©οΈ COPYRIGHT Β©οΈ
Copyright Β© 2015 Rick van Rein, ARPA2.net.
ARPA2 is funded from InternetWide.org, which in turn receives donations from various funding sources with an interest in a private and secure Internet that gives users control over their online presence. This particular project has been sponsored in part by NCSC.
π SEE ALSO π
The configuration file options allow_facilities and deny_facilities can specify the starttls facility to allow, respectively disable this facility. Whether this has been done can be checked with tlspool_ping(3).
The TLS Pool API is documented in the include file <tlspool/commands.h> and <tlspool/starttls.h> for C, and the tlspool.py module for Python.
Online resources may be found on the project home page, http://tlspool.arpa2.net.
muah π β sourced from ARPA2.net, dated November 2015, page TLSPOOL_STARTTLS(3), signing off β¨π«Ά
π¦ where this page comes from
- nixos 26.05: tlspool 0.9.7
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms