ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
oauth2.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file oauth2.h
6 * @brief OAuth2 token-endpoint client - authorization-code + refresh (PC_ENABLE_OAUTH2).
7 *
8 * The other half of the OAuth/OIDC story (services/security/oidc verifies the ID token;
9 * this obtains the tokens). A relying party exchanges an authorization code for
10 * tokens at the provider's token endpoint, or refreshes them, per RFC 6749 §4.1.3
11 * / §6:
12 *
13 * - **Pure core (host-tested):** build the `application/x-www-form-urlencoded`
14 * request body (proper percent-encoding) for the `authorization_code` and
15 * `refresh_token` grants, and parse the JSON token response (reusing the
16 * library's zero-heap JSON reader) into ::pc_o_auth2_tokens.
17 * - **ESP32 convenience (needs PC_ENABLE_HTTP_CLIENT):**
18 * pc_oauth2_exchange_code() / _refresh() POST to the token URL over the
19 * HTTP(S) client and parse the result.
20 *
21 * Supports a confidential client (client_secret) or a public client with PKCE
22 * (code_verifier, RFC 7636) - pass whichever applies, nullptr for the other. No
23 * heap, no stdlib.
24 *
25 * @author Douglas Quigg (dstroy0)
26 * @date 2026
27 */
28
29#ifndef PROTOCORE_OAUTH2_H
30#define PROTOCORE_OAUTH2_H
31
32#include "protocore_config.h"
33#include <stddef.h>
34#include <stdint.h>
35
36#if PC_ENABLE_OAUTH2
37
38/** @brief Tokens parsed from a token-endpoint response. Absent fields are empty / 0. */
39struct pc_o_auth2_tokens
40{
41 char access_token[PC_OAUTH2_TOKEN_LEN];
42 char id_token[PC_OAUTH2_TOKEN_LEN]; ///< OIDC ID token (verify with services/security/oidc).
43 char refresh_token[PC_OAUTH2_RT_LEN];
44 char token_type[24]; ///< usually "Bearer".
45 long expires_in; ///< access-token lifetime in seconds (0 if absent).
46};
47
48/** @brief oauth2 result codes (HTTP status codes are positive on success). */
49enum class pc_o_auth2_result : int32_t
50{
51 PC_OAUTH2_ERR_BUILD = -1, ///< request body did not fit @p cap.
52 PC_OAUTH2_ERR_TRANSPORT = -2, ///< HTTP client error (no DNS / TLS / connection).
53 PC_OAUTH2_ERR_RESPONSE = -3, ///< response was not a valid token JSON (no access_token).
54};
55
56// ---------------------------------------------------------------------------
57// Pure core (host-testable)
58// ---------------------------------------------------------------------------
59
60/**
61 * @brief Build the form body for the authorization_code grant.
62 *
63 * @param code,redirect_uri,client_id required parameters.
64 * @param client_secret confidential-client secret, or nullptr.
65 * @param code_verifier PKCE verifier (RFC 7636) for a public client, or nullptr.
66 * @return bytes written (excluding NUL), or 0 if it does not fit.
67 */
68int pc_oauth2_build_code_request(const char *code, const char *redirect_uri, const char *client_id,
69 const char *client_secret, const char *code_verifier, char *out, size_t cap);
70
71/**
72 * @brief Build the form body for the refresh_token grant.
73 * @return bytes written (excluding NUL), or 0 if it does not fit.
74 */
75int pc_oauth2_build_refresh_request(const char *refresh_token, const char *client_id, const char *client_secret,
76 char *out, size_t cap);
77
78/**
79 * @brief Parse a token-endpoint JSON response into @p out.
80 * @return true if an access_token is present (a usable token response).
81 */
82bool pc_oauth2_parse_token_response(const char *json, pc_o_auth2_tokens *out);
83
84#if PC_ENABLE_HTTP_CLIENT
85// ---------------------------------------------------------------------------
86// ESP32 convenience (over the HTTP(S) client)
87// ---------------------------------------------------------------------------
88
89/**
90 * @brief Exchange an authorization code at @p token_url for tokens.
91 * @return the HTTP status (200 on success) or a negative ::pc_o_auth2_result.
92 */
93int pc_oauth2_exchange_code(const char *token_url, const char *code, const char *redirect_uri, const char *client_id,
94 const char *client_secret, const char *code_verifier, pc_o_auth2_tokens *out);
95
96/**
97 * @brief Refresh tokens at @p token_url using a refresh token.
98 * @return the HTTP status (200 on success) or a negative ::pc_o_auth2_result.
99 */
100int pc_oauth2_refresh(const char *token_url, const char *refresh_token, const char *client_id,
101 const char *client_secret, pc_o_auth2_tokens *out);
102#endif
103
104#endif // PC_ENABLE_OAUTH2
105#endif // PROTOCORE_OAUTH2_H
User-facing configuration for ProtoCore.