forked from u-blox/ubxlib
-
Notifications
You must be signed in to change notification settings - Fork 1
/
u_cell_sec_tls.h
495 lines (450 loc) · 22.1 KB
/
u_cell_sec_tls.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
/*
* Copyright 2019-2023 u-blox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _U_CELL_SEC_TLS_H_
#define _U_CELL_SEC_TLS_H_
/* Only header files representing a direct and unavoidable
* dependency between the API of this module and the API
* of another module should be included here; otherwise
* please keep #includes to your .c files. */
/** \addtogroup _cell
* @{
*/
/** @file
* @brief This header file defines the TLS security APIs for a u-blox
* cellular module. Note that these functions are not intended to be
* called directly, they are called internally within ubxlib by the
* common TLS security API (common/security/api/u_security_tls.h)
* when a secure connection is requested by one of the common
* protocol APIs (e.g. common/sock). These functions are thread-safe
* unless otherwise stated.
*/
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------------------------------------------
* COMPILE-TIME MACROS
* -------------------------------------------------------------- */
#ifndef U_CELL_SEC_TLS_PSK_MAX_LENGTH_BYTES
/** The maximum length of a PSK array (binary, not hex encoded as ASCII).
*/
# define U_CELL_SEC_TLS_PSK_MAX_LENGTH_BYTES 64
#endif
#ifndef U_CELL_SEC_TLS_PSK_ID_MAX_LENGTH_BYTES
/** The maximum length of a PSK ID array (binary, not hex encoded as ASCII).
*/
# define U_CELL_SEC_TLS_PSK_ID_MAX_LENGTH_BYTES 128
#endif
/* ----------------------------------------------------------------
* TYPES
* -------------------------------------------------------------- */
/** The types of certificate checking that can be performed.
* NOTE: this must use the same values as the equivalent enum in
* u_security_tls.h.
*/
typedef enum {
U_CELL_SEC_TLS_CERTIFICATE_CHECK_NONE = 0x00, /**< no checking. */
U_CELL_SEC_TLS_CERTIFICATE_CHECK_ROOT_CA = 0x01, /**< check root CA. */
U_CELL_SEC_TLS_CERTIFICATE_CHECK_ROOT_CA_URL = 0x02, /**< check root CA and URL. */
U_CELL_SEC_TLS_CERTIFICATE_CHECK_ROOT_CA_URL_DATE = 0x03, /**< check root CA, URL and expiry date. */
U_CELL_SEC_TLS_CERTIFICATE_CHECK_MAX_NUM
} uCellSecTlsCertficateCheck_t;
/** Storage for a list of ciphers.
*/
typedef struct {
char *pString; /**< the cipher list string as returned by
AT+USECPRF, for example "C034;009e;CCAD...",
max length #U_CELL_SEC_CIPHERS_BUFFER_LENGTH_BYTES. */
size_t index; /**< which character we are at in the string. */
} uCellSecTlsCipherList_t;
/** A cellular TLS security context.
*/
typedef struct {
uDeviceHandle_t cellHandle; /**< the associated cellular handle. */
uCellSecTlsCipherList_t cipherList; /**< temporary storage for a cipher list. */
uint8_t profileId; /**< the associated security profile ID,
at the end to improve structure packing. */
} uCellSecTlsContext_t;
/* ----------------------------------------------------------------
* FUNCTIONS: WORKAROUND FOR LINKER ISSUE
* -------------------------------------------------------------- */
/** Workaround for Espressif linker missing out files that
* only contain functions which also have weak alternatives
* (see https://www.esp32.com/viewtopic.php?f=13&t=8418&p=35899).
*
* You can ignore this function.
*/
void uCellSecTlsPrivateLink(void);
/* ----------------------------------------------------------------
* FUNCTIONS: ADD/REMOVE A TLS SECURITY CONTEXT
* -------------------------------------------------------------- */
/** Add a cellular TLS security context (AKA profile) with default
* settings. This function is called internally within ubxlib by
* the common TLS security API
* (common/security/api/u_security_tls.h) when a secure connection
* is requested by one of the common protocol APIs (e.g. common/sock).
*
* @param cellHandle the handle of the cellular instance.
* @return on success a pointer to the TLS security context,
* else NULL, in which case
* uCellSecTlsResetLastError() should be called to
* determine the cause of the failure).
*/
uCellSecTlsContext_t *pUCellSecSecTlsAdd(uDeviceHandle_t cellHandle);
/** Remove a cellular TLS security context. This function is called
* internally within ubxlib by the common TLS security API
* (common/security/api/u_security_tls.h) when a secure connection
* is closed by one of the common protocol APIs (e.g. common/sock).
*
* @param[in] pContext a pointer to the TLS security context.
*/
void uCellSecTlsRemove(uCellSecTlsContext_t *pContext);
/** Get the last error that occurred in this API. This must
* be called if pUCellSecTlsAdd() returned NULL to find out
* why. The error code is reset to "success" by this function.
*
* @return the last error code.
*/
int32_t uCellSecTlsResetLastError();
/* ----------------------------------------------------------------
* FUNCTIONS: CONFIGURE CERTIFICATES/SECRETS
* -------------------------------------------------------------- */
/** Set the name of the root CA X.509 certificate to use.
* The X.509 certificate must have been stored in the module
* using uSecurityCredentialStore().
*
* @param[in] pContext a pointer to the security context.
* @param pName the null-terminated name of the root CA
* X.509 certificate, as stored using
* uSecurityCredentialStore().
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsRootCaCertificateNameSet(const uCellSecTlsContext_t *pContext,
const char *pName);
/** Get the name of the root CA X.509 certificate in use.
* The X.509 certificate must have been stored in the module
* using uSecurityCredentialStore().
*
* @param[in] pContext a pointer to the security context.
* @param[out] pName a pointer to a place to store the name of
* the root CA X.509 certificate; the name
* will be a null-terminated string.
* @param size the number of bytes of storage at
* pName; to ensure sufficient space at least
* #U_SECURITY_CREDENTIAL_NAME_MAX_LENGTH_BYTES + 1
* bytes should be provided.
* @return on success the length of the string
* stored at pName (i.e. what strlen() would
* return) else negative error code.
*/
int32_t uCellSecTlsRootCaCertificateNameGet(const uCellSecTlsContext_t *pContext,
char *pName,
size_t size);
/** Set the name of the client X.509 certificate to use.
* The X.509 certificate must have been stored in the module
* using uSecurityCredentialStore(). See also
* uCellSecTlsUseDeviceCertificateSet() below.
*
* @param[in] pContext a pointer to the security context.
* @param[in] pName the null-terminated name of the client
* X.509 certificate, as stored using
* uSecurityCredentialStore().
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsClientCertificateNameSet(const uCellSecTlsContext_t *pContext,
const char *pName);
/** Get the name of the client X.509 certificate in use.
* The X.509 certificate must have been stored in the module
* using uSecurityCredentialStore().
*
* @param[in] pContext a pointer to the security context.
* @param[out] pName a pointer to a place to store the name of
* the client X.509 certificate; the name
* will be a null-terminated string.
* @param size the number of bytes of storage at
* pName; to ensure sufficient space at least
* #U_SECURITY_CREDENTIAL_NAME_MAX_LENGTH_BYTES + 1
* bytes should be provided.
* @return on success the length of the string
* stored at pName (i.e. what strlen() would
* return) else negative error code.
*/
int32_t uCellSecTlsClientCertificateNameGet(const uCellSecTlsContext_t *pContext,
char *pName,
size_t size);
/** Set the name of the client private key to use and, if required
* the associated password. The key must have been stored in the
* module using uSecurityCredentialStore().
*
* @param[in] pContext a pointer to the security context.
* @param[in] pName the null-terminated name of the client private
* key, as stored using uSecurityCredentialStore().
* @param[in] pPassword the null-terminated password for the client
* private key; use NULL if the key is not
* password-protected.
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsClientPrivateKeyNameSet(const uCellSecTlsContext_t *pContext,
const char *pName,
const char *pPassword);
/** Get the name of the client private key in use. The key
* must have been stored in the module using uSecurityCredentialStore().
*
* @param[in] pContext a pointer to the security context.
* @param[out] pName a pointer to a place to store the name of
* the client private key; the name
* will be a null-terminated string.
* @param size the number of bytes of storage at
* pName; to ensure sufficient space at least
* #U_SECURITY_CREDENTIAL_NAME_MAX_LENGTH_BYTES + 1
* bytes should be provided.
* @return on success the length of the string
* stored at pName (i.e. what strlen() would
* return) else negative error code.
*/
int32_t uCellSecTlsClientPrivateKeyNameGet(const uCellSecTlsContext_t *pContext,
char *pName,
size_t size);
/** Set the pre-shared key and pre-shared key identity to use.
* IMPORTANT: on all currently supported modules the PSK and
* PSK ID must include no ASCII control characters.
*
* @param[in] pContext a pointer to the security context.
* @param[in] pPsk the pre-shared key to use, encoded as binary,
* for example [0x0a, 0x04, 0xf0, 0x08... etc],
* *not* hex encoded in ASCII; cannot be NULL.
* @param pskLengthBytes the amount of data at pPsk, must be no
* more than #U_SECURITY_TLS_PSK_MAX_LENGTH_BYTES.
* @param[in] pPskId the pre-shared key ID to use, encoded as binary,
* for example [0x0a, 0x04, 0xf0, 0x08... etc],
* *not* hex encoded in ASCII; cannot be NULL.
* @param pskIdLengthBytes the amount of data at pPskId, must be no
* more than #U_SECURITY_TLS_PSK_ID_MAX_LENGTH_BYTES.
* @param generate if this is set to true then, where supported,
* the root of trust inside the cellular module
* will generate the pre-shared key and
* pre-shared key identity; pPsk and pPskId
* must be set to NULL.
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsClientPskSet(const uCellSecTlsContext_t *pContext,
const char *pPsk, size_t pskLengthBytes,
const char *pPskId, size_t pskIdLengthBytes,
bool generate);
/** If this returns successfully then, for a module which supports u-blox
* security and has been security sealed, the device public X.509 certificate
* that was generated at security sealing will be used as the client
* certificate.
*
* @param[in] pContext a pointer to the security context.
* @param includeCaCertificates if set to true then the CA X.509 certificates
* that were used to sign the device
* certificate during the security sealing
* process will also be included.
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsUseDeviceCertificateSet(const uCellSecTlsContext_t *pContext,
bool includeCaCertificates);
/** Get whether the device public X.509 certificate that was generated at
* security sealing is being used as the client certificate.
*
* @param[in] pContext a pointer to the security context.
* @param[out] pIncludeCaCertificates a place to store whether the CA X.509
* certificates that were used to sign the device
* certificate during the security sealing
* process are also being included; may be NULL.
* @return true if the device public X.509 certificate
* is being usd as the cient certificate, else
* false (and the name set with the call to
* uCellSecTlsClientCertificateNameSet() is being
* used instead).
*/
bool uCellSecTlsIsUsingDeviceCertificate(const uCellSecTlsContext_t *pContext,
bool *pIncludeCaCertificates);
/* ----------------------------------------------------------------
* FUNCTIONS: CONFIGURE CIPHER SUITE
* -------------------------------------------------------------- */
/** Add a cipher suite to the set in use. Not all u-blox modules
* support all cipher suites, consult the security section of your
* u-blox module AT manual for further information.
* Note that the SARA-U201 and SARA-R4xx modules support only a
* single configurable cipher suite and adding a new one will
* overwrite the previous.
*
* @param[in] pContext a pointer to the security context.
* @param ianaNumber the IANA number of the cipher suite to add.
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsCipherSuiteAdd(const uCellSecTlsContext_t *pContext,
int32_t ianaNumber);
/** Remove a cipher suite from the set in use.
* Note: since the SARA-U201 and SARA-R4xx modules support only a
* single configurable cipher suite this function will remove that
* cipher suite, whatever the value of ianaNumber; effectively
* a "reset to default" call.
*
* @param[in] pContext a pointer to the security context.
* @param ianaNumber the IANA number of the cipher suite to remove.
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsCipherSuiteRemove(const uCellSecTlsContext_t *pContext,
int32_t ianaNumber);
/** Get the first cipher suite in use; uCellSecTlsCipherSuiteListNext()
* should be called repeatedly to iterate through subsequent entries
* in the list. This function is not thread-safe in that there
* is a single list of names for any given security context.
* The SARA-U201 and SARA-R4xx modules do not support this feature.
*
* For instance, to print out all of the cipher suites in use:
*
* ```
* for (int32_t x = uCellSecTlsCipherSuiteListFirst(pContext);
* x >= 0;
* x = uCellSecTlsCipherSuiteListNext(pContext)) {
* printf("0x%04x\n", x);
* }
* ```
*
* @param[in] pContext a pointer to the security context.
* @return the IANA number of the cipher suite or
* negative error code.
*/
int32_t uCellSecTlsCipherSuiteListFirst(uCellSecTlsContext_t *pContext);
/** Get the subsequent cipher suite in use. Use
* uCellSecTlsCipherSuiteListFirst() to get the first entry
* and then call this until an error is returned to read out all
* of the entries; this will free the memory that held the
* list after the final call (otherwise it will be freed when the
* security context is removed or another cipher suite list
* is initiated, or can be freed with a call to
* uCellSecTlsCipherSuiteListLast()). This function is not
* thread-safe in that there is a single list for any given
* security context.
* The SARA-U201 and SARA-R4xx modules do not support this feature.
*
* @param[in] pContext a pointer to the security context.
* @return the IANA number of the cipher suite or
* negative error code.
*/
int32_t uCellSecTlsCipherSuiteListNext(uCellSecTlsContext_t *pContext);
/** It is good practice to call this to clear up memory from
* uCellSecTlsCipherSuiteListFirst() if you are not going to
* iterate through the whole list with
* uCellSecTlsCipherSuiteListNext().
*
* @param[in] pContext a pointer to the security context.
*/
void uCellSecTlsCipherSuiteListLast(uCellSecTlsContext_t *pContext);
/* ----------------------------------------------------------------
* FUNCTIONS: MISC SETTINGS
* -------------------------------------------------------------- */
/** Set the minimum [D]TLS version to use. If this is not called
* the version will be "any".
*
* @param[in] pContext a pointer to the security context.
* @param tlsVersionMin the [D]TLS version encoded as an integer
* where 0 = any, 10 = 1.0, 11 = 1.1 and
* 12 = 1.2.
* @return zero on success else negative error code.
*/
int32_t uCellSecTlsVersionSet(const uCellSecTlsContext_t *pContext,
int32_t tlsVersionMin);
/** Get the minimum [D]TLS version in use.
*
* @param[in] pContext a pointer to the security context.
* @return on success the [D]TLS version (see
* uCellSecTlsVersionSet() for encoding), else
* negative error code.
*/
int32_t uCellSecTlsVersionGet(const uCellSecTlsContext_t *pContext);
/** Set the type of checking to perform on certificates
* received from the server. If this is not called the certificate
* checking carried out will depend upon the module: for SARA-R5
* and SARA-R422 root CA checking is conducted, on all other cellular
* modules no checking is conducted.
*
* @param[in] pContext a pointer to the security context.
* @param check the certificate checks to perform.
* @param[in] pUrl if URL checking is included this must
* be the null-terminated server URL
* to check against, else it must be NULL;
* should be no longer than
* #U_SECURITY_TLS_EXPECTED_SERVER_URL_MAX_LENGTH_BYTES
* bytes long, excluding the terminator.
* @return zero on success else negative error
* code.
*/
int32_t uCellSecTlsCertificateCheckSet(const uCellSecTlsContext_t *pContext,
uCellSecTlsCertficateCheck_t check,
const char *pUrl);
/** Get the type of checking being performed on certificates
* received from the server.
*
* @param[in] pContext a pointer to the security context.
* @param[out] pUrl a pointer to a place to store the
* null-terminated server URL being checked
* against; only populated if URL-checking
* is included, may be NULL.
* @param size the amount of storage at pUrl. To ensure
* no loss
* #U_SECURITY_TLS_EXPECTED_SERVER_URL_MAX_LENGTH_BYTES + 1
* bytes should be allowed.
* @return the certificate check being performed
* or negative error code.
*/
int32_t uCellSecTlsCertificateCheckGet(const uCellSecTlsContext_t *pContext,
char *pUrl, size_t size);
/** Set the optional Server Name Indication string which
* can be used during TLS negotiation. If this is not called no
* Server Name Indication checking will be carried out.
* The SARA-U201 and SARA-R4xx modules do not support this feature.
*
* @param[in] pContext a pointer to the security context.
* @param[in] pSni the null-terminated server name
* indication string to check against,
* should be no longer than
* #U_SECURITY_TLS_SNI_MAX_LENGTH_BYTES
* bytes long, excluding the terminator;
* use NULL to cancel any existing Server
* Name Indication checking.
* @return zero on success else negative error
* code.
*/
int32_t uCellSecTlsSniSet(const uCellSecTlsContext_t *pContext,
const char *pSni);
/** Get the optional Server Name Indication string which is
* being used during TLS negotiation.
* The SARA-U201 and SARA-R4xx modules do not support this feature.
*
* @param pContext a pointer to the security context.
* @param[out] pSni a pointer to a place to store the
* null-terminated Server Name Indication
* string.
* @param size the amount of storage at pSni; to ensure
* no loss
* #U_SECURITY_TLS_SNI_MAX_LENGTH_BYTES + 1
* bytes should be allowed.
* @return on success the length of the string
* stored at pSni (i.e. what strlen() would
* return) else negative error code.
*/
int32_t uCellSecTlsSniGet(const uCellSecTlsContext_t *pContext,
char *pSni, size_t size);
#ifdef __cplusplus
}
#endif
/** @}*/
#endif // _U_CELL_SEC_TLS_H_
// End of file