ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
spnego.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4#ifndef PROTOCORE_SPNEGO_H
5#define PROTOCORE_SPNEGO_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file spnego.h
13 * @brief SPNEGO (RFC 4178) GSS-API wrapping of the NTLMSSP tokens for the SMB2 client
14(PROTOCORE_ENABLE_SMB).
15 *
16 * SMB2 SESSION_SETUP carries the NTLM handshake tokens inside a SPNEGO negotiation token. This is
17 * the minimal ASN.1 DER layer that a client needs:
18 * - the first client token is a GSS-API InitialContextToken: `[APPLICATION 0] { SPNEGO-OID,
19 * NegTokenInit [0] { mechTypes [0] { NTLM-OID }, mechToken [2] OCTET STRING(NTLMSSP NEGOTIATE) } }`;
20 * - the server replies with a bare NegTokenResp `[1] { ..., responseToken [2] OCTET STRING(NTLMSSP
21 * CHALLENGE) }`, from which the client extracts the CHALLENGE;
22 * - the client's second token is a NegTokenResp `[1] { responseToken [2] OCTET STRING(NTLMSSP
23 * AUTHENTICATE) }`.
24 *
25 * Pure DER, zero heap, definite-length only. The NTLM tokens come from ntlmssp.h.
26 *
27 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
28 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
29 * a caller drives every namespace the same way.
30 *
31 * @author Douglas Quigg (dstroy0)
32 * @date 2026
33 */
34
35// PROTOCORE_SPNEGO_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
36// it into its arena. Its size and its offset are each a static_assert, so a feature
37// combination that does not fit fails to compile rather than overrunning at run time.
38
39/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
40typedef struct
41{
42 size_t (*wrap_negotiate)(uint8_t *, const uint8_t *, size_t, uint8_t *, size_t);
43 proto_bool (*parse_response)(uint8_t *, const uint8_t *, size_t, const uint8_t **, size_t *);
44 size_t (*wrap_authenticate)(uint8_t *, const uint8_t *, size_t, uint8_t *, size_t);
45} SpnegoNs;
46PROTOCORE_NS_LAYOUT(SpnegoNs, wrap_negotiate, parse_response, wrap_authenticate);
47
48/**
49 * @brief Wrap an NTLMSSP NEGOTIATE token in a SPNEGO GSS-API .
50 * @param work PROTOCORE_SPNEGO_BORROW bytes the caller took. Not held past the call.
51 * @param ntlm Ntlm
52 * @param protocore_ntlm_len Protocore ntlm len
53 * @param out Out
54 * @param cap Cap
55 * @return The size_t.
56 */
57size_t protocore_spnego_wrap_negotiate(uint8_t *work, const uint8_t *ntlm, size_t protocore_ntlm_len, uint8_t *out,
58 size_t cap);
59/**
60 * @brief Extract the responseToken (the NTLMSSP CHALLENGE) from a server .
61 * @param work PROTOCORE_SPNEGO_BORROW bytes the caller took. Not held past the call.
62 * @param blob Blob
63 * @param len Len
64 * @param protocore_resp_token receives a pointer INTO blob; protocore_resp_len its length
65 * @param protocore_resp_len Protocore resp len
66 * @return PROTO_TRUE on success.
67 */
68proto_bool protocore_spnego_parse_response(uint8_t *work, const uint8_t *blob, size_t len,
69 const uint8_t **protocore_resp_token, size_t *protocore_resp_len);
70/**
71 * @brief Wrap an NTLMSSP AUTHENTICATE token in a SPNEGO NegTokenResp (the .
72 * @param work PROTOCORE_SPNEGO_BORROW bytes the caller took. Not held past the call.
73 * @param ntlm Ntlm
74 * @param protocore_ntlm_len Protocore ntlm len
75 * @param out Out
76 * @param cap Cap
77 * @return The size_t.
78 */
79size_t protocore_spnego_wrap_authenticate(uint8_t *work, const uint8_t *ntlm, size_t protocore_ntlm_len, uint8_t *out,
80 size_t cap);
81
82/** @brief Module namespace. */
86
88
89#endif // PROTOCORE_SPNEGO_H
#define PROTOCORE_NS_LAYOUT(T,...)
Pin every dispatch slot of a table that is nothing but function pointers.
#define PROTOCORE_NS
Storage for a dispatch table. The const is load bearing.
proto_bool protocore_spnego_parse_response(uint8_t *work, const uint8_t *blob, size_t len, const uint8_t **protocore_resp_token, size_t *protocore_resp_len)
Extract the responseToken (the NTLMSSP CHALLENGE) from a server .
size_t protocore_spnego_wrap_authenticate(uint8_t *work, const uint8_t *ntlm, size_t protocore_ntlm_len, uint8_t *out, size_t cap)
Wrap an NTLMSSP AUTHENTICATE token in a SPNEGO NegTokenResp (the .
size_t protocore_spnego_wrap_negotiate(uint8_t *work, const uint8_t *ntlm, size_t protocore_ntlm_len, uint8_t *out, size_t cap)
Wrap an NTLMSSP NEGOTIATE token in a SPNEGO GSS-API .
PROTOCORE_NS SpnegoNs Spnego PROTOCORE_UNUSED
Module namespace.
Definition spnego.h:83
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition spnego.h:41
size_t(* wrap_negotiate)(uint8_t *, const uint8_t *, size_t, uint8_t *, size_t)
Definition spnego.h:42
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97