1 /*
2  * Copyright (c) 2018 Linaro Ltd
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DATA_JWT_H_
8 #define ZEPHYR_INCLUDE_DATA_JWT_H_
9 
10 #include <zephyr/types.h>
11 #include <stdbool.h>
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /**
18  * @brief JSON Web Token (JWT) - RFC 7519
19  * @defgroup jwt JSON Web Token (JWT)
20  * @ingroup json
21  * @{
22  */
23 
24 /**
25  * @brief JWT data tracking.
26  *
27  * JSON Web Tokens contain several sections, each encoded in Base64URL.
28  * This structure tracks the token as it is being built, including
29  * limits on the amount of available space.  It should be initialized
30  * with jwt_init_builder().
31  */
32 struct jwt_builder {
33 	/** The base of the buffer we are writing to. */
34 	char *base;
35 
36 	/** The place in this buffer where we are currently writing.
37 	 */
38 	char *buf;
39 
40 	/** The remaining free space in @p buf. */
41 	size_t len;
42 
43 	/**
44 	 * Flag that is set if we try to write past the end of the
45 	 * buffer.  If set, the token is not valid.
46 	 */
47 	bool overflowed;
48 
49 	/* Pending bytes yet to be converted to base64. */
50 	unsigned char wip[3];
51 
52 	/* Number of pending bytes. */
53 	int pending;
54 };
55 
56 /**
57  * @brief Initialize the JWT builder.
58  *
59  * Initialize the given JWT builder for the creation of a fresh token.
60  * The buffer size should be long enough to store the entire token.
61  *
62  * @param builder The builder to initialize.
63  * @param buffer The buffer to write the token to.
64  * @param buffer_size The size of this buffer.  The token will be NULL
65  * terminated, which needs to be allowed for in this size.
66  *
67  * @retval 0 Success.
68  * @retval -ENOSPC Buffer is insufficient to initialize.
69  */
70 int jwt_init_builder(struct jwt_builder *builder,
71 		     char *buffer,
72 		     size_t buffer_size);
73 
74 /**
75  * @brief Add JWT payload.
76  *
77  * Add JWT payload to a previously initialized builder with the following fields:
78  * - Expiration Time
79  * - Issued At
80  * - Audience
81  *
82  * See RFC 7519 section 4.1 to get more information about these fields.
83  *
84  * @param builder A previously initialized builder.
85  * @param exp Expiration Time (epoch format).
86  * @param iat Issued At (epoch format).
87  * @param aud Audience.
88  *
89  * @retval 0 Success.
90  * @retval <0 Failure.
91  */
92 int jwt_add_payload(struct jwt_builder *builder,
93 		    int32_t exp,
94 		    int32_t iat,
95 		    const char *aud);
96 
97 /**
98  * @brief Sign the JWT.
99  *
100  * Sign a previously initialized with payload JWT.
101  *
102  * @param builder A previously initialized builder with payload.
103  * @param der_key Private key to use in DER format.
104  * @param der_key_len Size of the private key in bytes.
105  *
106  * @retval 0 Success.
107  * @retval <0 Failure.
108  */
109 int jwt_sign(struct jwt_builder *builder,
110 	     const char *der_key,
111 	     size_t der_key_len);
112 
113 #ifdef __cplusplus
114 }
115 #endif
116 
117 /**
118  * @}
119  */
120 
121 #endif /* ZEPHYR_INCLUDE_DATA_JWT_H_ */
122