net/handshake/tlshd.c

Source file repositories/reference/linux-study-clean/net/handshake/tlshd.c

File Facts

System
Linux kernel
Corpus path
net/handshake/tlshd.c
Extension
.c
Size
12352 bytes
Lines
458
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tls_handshake_req {
	void			(*th_consumer_done)(void *data, int status,
						    key_serial_t peerid);
	void			*th_consumer_data;

	int			th_type;
	unsigned int		th_timeout_ms;
	int			th_auth_mode;
	const char		*th_peername;
	key_serial_t		th_keyring;
	key_serial_t		th_certificate;
	key_serial_t		th_privkey;

	unsigned int		th_num_peerids;
	key_serial_t		th_peerid[5];
};

static struct tls_handshake_req *
tls_handshake_req_init(struct handshake_req *req,
		       const struct tls_handshake_args *args)
{
	struct tls_handshake_req *treq = handshake_req_private(req);

	treq->th_timeout_ms = args->ta_timeout_ms;
	treq->th_consumer_done = args->ta_done;
	treq->th_consumer_data = args->ta_data;
	treq->th_peername = args->ta_peername;
	treq->th_keyring = args->ta_keyring;
	treq->th_num_peerids = 0;
	treq->th_certificate = TLS_NO_CERT;
	treq->th_privkey = TLS_NO_PRIVKEY;
	return treq;
}

static void tls_handshake_remote_peerids(struct tls_handshake_req *treq,
					 struct genl_info *info)
{
	struct nlattr *head = nlmsg_attrdata(info->nlhdr, GENL_HDRLEN);
	int rem, len = nlmsg_attrlen(info->nlhdr, GENL_HDRLEN);
	struct nlattr *nla;
	unsigned int i;

	i = 0;
	nla_for_each_attr(nla, head, len, rem) {
		if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
			i++;
	}
	if (!i)
		return;
	treq->th_num_peerids = min_t(unsigned int, i,
				     ARRAY_SIZE(treq->th_peerid));

	i = 0;
	nla_for_each_attr(nla, head, len, rem) {
		if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
			treq->th_peerid[i++] = nla_get_u32(nla);
		if (i >= treq->th_num_peerids)
			break;
	}
}

/**
 * tls_handshake_done - callback to handle a CMD_DONE request
 * @req: socket on which the handshake was performed
 * @status: session status code
 * @info: full results of session establishment
 *
 */
static void tls_handshake_done(struct handshake_req *req,
			       int status, struct genl_info *info)
{
	struct tls_handshake_req *treq = handshake_req_private(req);

	treq->th_peerid[0] = TLS_NO_PEERID;
	if (info)
		tls_handshake_remote_peerids(treq, info);

	if (!status)
		set_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags);

	treq->th_consumer_done(treq->th_consumer_data, status,
			       treq->th_peerid[0]);
}

#if IS_ENABLED(CONFIG_KEYS)
static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
{
	key_ref_t process_keyring_ref, keyring_ref;
	int ret;

Annotation

Implementation Notes