-
Notifications
You must be signed in to change notification settings - Fork 7.6k
/
Copy pathcoap_dtls.h
485 lines (431 loc) · 19.3 KB
/
coap_dtls.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
/*
* coap_dtls.h -- (Datagram) Transport Layer Support for libcoap
*
* Copyright (C) 2016 Olaf Bergmann <[email protected]>
* Copyright (C) 2017 Jean-Claude Michelou <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_DTLS_H_
#define COAP_DTLS_H_
#include "coap_time.h"
#include "str.h"
/**
* @defgroup dtls DTLS Support
* API functions for interfacing with DTLS libraries.
* @{
*/
typedef struct coap_dtls_pki_t coap_dtls_pki_t;
#ifndef COAP_DTLS_HINT_LENGTH
#define COAP_DTLS_HINT_LENGTH 128
#endif
#ifndef COAP_DTLS_MAX_PSK_IDENTITY
#define COAP_DTLS_MAX_PSK_IDENTITY 64
#endif
#ifndef COAP_DTLS_MAX_PSK
#define COAP_DTLS_MAX_PSK 64
#endif
typedef enum coap_dtls_role_t {
COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */
COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */
} coap_dtls_role_t;
#define COAP_DTLS_RPK_CERT_CN "RPK"
/**
* Check whether DTLS is available.
*
* @return @c 1 if support for DTLS is enabled, or @c 0 otherwise.
*/
int coap_dtls_is_supported(void);
/**
* Check whether TLS is available.
*
* @return @c 1 if support for TLS is enabled, or @c 0 otherwise.
*/
int coap_tls_is_supported(void);
typedef enum coap_tls_library_t {
COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */
COAP_TLS_LIBRARY_TINYDTLS, /**< Using TinyDTLS library */
COAP_TLS_LIBRARY_OPENSSL, /**< Using OpenSSL library */
COAP_TLS_LIBRARY_GNUTLS, /**< Using GnuTLS library */
COAP_TLS_LIBRARY_MBEDTLS, /**< Using Mbed TLS library */
} coap_tls_library_t;
/**
* The structure used for returning the underlying (D)TLS library
* information.
*/
typedef struct coap_tls_version_t {
uint64_t version; /**< (D)TLS runtime Library Version */
coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */
uint64_t built_version; /**< (D)TLS Built against Library Version */
} coap_tls_version_t;
/**
* Determine the type and version of the underlying (D)TLS library.
*
* @return The version and type of library libcoap was compiled against.
*/
coap_tls_version_t *coap_get_tls_library_version(void);
/**
* Additional Security setup handler that can be set up by
* coap_context_set_pki().
* Invoked when libcoap has done the validation checks at the TLS level,
* but the application needs to do some additional checks/changes/updates.
*
* @param tls_session The security session definition - e.g. SSL * for OpenSSL.
* NULL if server callback.
* This will be dependent on the underlying TLS library -
* see coap_get_tls_library_version()
* @param setup_data A structure containing setup data originally passed into
* coap_context_set_pki() or coap_new_client_session_pki().
*
* @return @c 1 if successful, else @c 0.
*/
typedef int (*coap_dtls_security_setup_t)(void* tls_session,
coap_dtls_pki_t *setup_data);
/**
* CN Validation callback that can be set up by coap_context_set_pki().
* Invoked when libcoap has done the validation checks at the TLS level,
* but the application needs to check that the CN is allowed.
* CN is the SubjectAltName in the cert, if not present, then the leftmost
* Common Name (CN) component of the subject name.
* NOTE: If using RPK, then the Public Key does not contain a CN, but the
* content of COAP_DTLS_RPK_CERT_CN is presented for the @p cn parameter.
*
* @param cn The determined CN from the certificate
* @param asn1_public_cert The ASN.1 DER encoded X.509 certificate
* @param asn1_length The ASN.1 length
* @param coap_session The CoAP session associated with the certificate update
* @param depth Depth in cert chain. If 0, then client cert, else a CA
* @param validated TLS layer can find no issues if 1
* @param arg The same as was passed into coap_context_set_pki()
* in setup_data->cn_call_back_arg
*
* @return @c 1 if accepted, else @c 0 if to be rejected.
*/
typedef int (*coap_dtls_cn_callback_t)(const char *cn,
const uint8_t *asn1_public_cert,
size_t asn1_length,
coap_session_t *coap_session,
unsigned int depth,
int validated,
void *arg);
/**
* The enum used for determining the provided PKI ASN.1 (DER) Private Key
* formats.
*/
typedef enum coap_asn1_privatekey_type_t {
COAP_ASN1_PKEY_NONE, /**< NONE */
COAP_ASN1_PKEY_RSA, /**< RSA type */
COAP_ASN1_PKEY_RSA2, /**< RSA2 type */
COAP_ASN1_PKEY_DSA, /**< DSA type */
COAP_ASN1_PKEY_DSA1, /**< DSA1 type */
COAP_ASN1_PKEY_DSA2, /**< DSA2 type */
COAP_ASN1_PKEY_DSA3, /**< DSA3 type */
COAP_ASN1_PKEY_DSA4, /**< DSA4 type */
COAP_ASN1_PKEY_DH, /**< DH type */
COAP_ASN1_PKEY_DHX, /**< DHX type */
COAP_ASN1_PKEY_EC, /**< EC type */
COAP_ASN1_PKEY_HMAC, /**< HMAC type */
COAP_ASN1_PKEY_CMAC, /**< CMAC type */
COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */
COAP_ASN1_PKEY_HKDF /**< HKDF type */
} coap_asn1_privatekey_type_t;
/**
* The enum used for determining the PKI key formats.
*/
typedef enum coap_pki_key_t {
COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM file */
COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) buffer */
COAP_PKI_KEY_PEM_BUF, /**< The PKI key type is PEM buffer */
COAP_PKI_KEY_PKCS11, /**< The PKI key type is PKCS11 (DER) */
} coap_pki_key_t;
/**
* The structure that holds the PKI PEM definitions.
*/
typedef struct coap_pki_key_pem_t {
const char *ca_file; /**< File location of Common CA in PEM format */
const char *public_cert; /**< File location of Public Cert */
const char *private_key; /**< File location of Private Key in PEM format */
} coap_pki_key_pem_t;
/**
* The structure that holds the PKI PEM buffer definitions.
* The certificates and private key data must be in PEM format.
*
* Note: The Certs and Key should be NULL terminated strings for
* performance reasons (to save a potential buffer copy) and the length include
* this NULL terminator. It is not a requirement to have the NULL terminator
* though and the length must then reflect the actual data size.
*/
typedef struct coap_pki_key_pem_buf_t {
const uint8_t *ca_cert; /**< PEM buffer Common CA Cert */
const uint8_t *public_cert; /**< PEM buffer Public Cert, or Public Key if RPK */
const uint8_t *private_key; /**< PEM buffer Private Key
If RPK and 'EC PRIVATE KEY' this can be used
for both the public_cert and private_key */
size_t ca_cert_len; /**< PEM buffer CA Cert length */
size_t public_cert_len; /**< PEM buffer Public Cert length */
size_t private_key_len; /**< PEM buffer Private Key length */
} coap_pki_key_pem_buf_t;
/**
* The structure that holds the PKI ASN.1 (DER) definitions.
*/
typedef struct coap_pki_key_asn1_t {
const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */
const uint8_t *public_cert; /**< ASN1 (DER) Public Cert, or Public Key if RPK */
const uint8_t *private_key; /**< ASN1 (DER) Private Key */
size_t ca_cert_len; /**< ASN1 CA Cert length */
size_t public_cert_len; /**< ASN1 Public Cert length */
size_t private_key_len; /**< ASN1 Private Key length */
coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */
} coap_pki_key_asn1_t;
/**
* The structure that holds the PKI PKCS11 definitions.
*/
typedef struct coap_pki_key_pkcs11_t {
const char *ca; /**< pkcs11: URI for Common CA Certificate */
const char *public_cert; /**< pkcs11: URI for Public Cert */
const char *private_key; /**< pkcs11: URI for Private Key */
const char *user_pin; /**< User pin to access PKCS11. If NULL, then
pin-value= parameter must be set in
pkcs11: URI as a query. */
} coap_pki_key_pkcs11_t;
/**
* The structure that holds the PKI key information.
*/
typedef struct coap_dtls_key_t {
coap_pki_key_t key_type; /**< key format type */
union {
coap_pki_key_pem_t pem; /**< for PEM file keys */
coap_pki_key_pem_buf_t pem_buf; /**< for PEM memory keys */
coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) memory keys */
coap_pki_key_pkcs11_t pkcs11; /**< for PKCS11 keys */
} key;
} coap_dtls_key_t;
/**
* Server Name Indication (SNI) Validation callback that can be set up by
* coap_context_set_pki().
* Invoked if the SNI is not previously seen and prior to sending a certificate
* set back to the client so that the appropriate certificate set can be used
* based on the requesting SNI.
*
* @param sni The requested SNI
* @param arg The same as was passed into coap_context_set_pki()
* in setup_data->sni_call_back_arg
*
* @return New set of certificates to use, or @c NULL if SNI is to be rejected.
*/
typedef coap_dtls_key_t *(*coap_dtls_pki_sni_callback_t)(const char *sni,
void* arg);
#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */
/**
* The structure used for defining the PKI setup data to be used.
*/
struct coap_dtls_pki_t {
uint8_t version; /** Set to COAP_DTLS_PKI_SETUP_VERSION
to support this version of the struct */
/* Options to enable different TLS functionality in libcoap */
uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */
uint8_t check_common_ca; /**< 1 if peer cert is to be signed by
* the same CA as the local cert */
uint8_t allow_self_signed; /**< 1 if self-signed certs are allowed.
* Ignored if check_common_ca set */
uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */
uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */
uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */
uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */
uint8_t allow_no_crl; /**< 1 ignore if CRL not there */
uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */
uint8_t allow_bad_md_hash; /**< 1 if unsupported MD hashes are allowed */
uint8_t allow_short_rsa_length; /**< 1 if small RSA keysizes are allowed */
uint8_t is_rpk_not_cert; /**< 1 is RPK instead of Public Certificate.
* If set, PKI key format type cannot be
* COAP_PKI_KEY_PEM */
uint8_t reserved[3]; /**< Reserved - must be set to 0 for
future compatibility */
/* Size of 3 chosen to align to next
* parameter, so if newly defined option
* it can use one of the reserverd slot so
* no need to change
* COAP_DTLS_PKI_SETUP_VERSION and just
* decrement the reserved[] count.
*/
/** CN check callback function.
* If not NULL, is called when the TLS connection has passed the configured
* TLS options above for the application to verify if the CN is valid.
*/
coap_dtls_cn_callback_t validate_cn_call_back;
void *cn_call_back_arg; /**< Passed in to the CN callback function */
/** SNI check callback function.
* If not @p NULL, called if the SNI is not previously seen and prior to
* sending a certificate set back to the client so that the appropriate
* certificate set can be used based on the requesting SNI.
*/
coap_dtls_pki_sni_callback_t validate_sni_call_back;
void *sni_call_back_arg; /**< Passed in to the sni callback function */
/** Additional Security callback handler that is invoked when libcoap has
* done the standard, defined validation checks at the TLS level,
* If not @p NULL, called from within the TLS Client Hello connection
* setup.
*/
coap_dtls_security_setup_t additional_tls_setup_call_back;
char* client_sni; /**< If not NULL, SNI to use in client TLS setup.
Owned by the client app and must remain valid
during the call to coap_new_client_session_pki() */
coap_dtls_key_t pki_key; /**< PKI key definition */
};
/**
* The structure that holds the Client PSK information.
*/
typedef struct coap_dtls_cpsk_info_t {
coap_bin_const_t identity;
coap_bin_const_t key;
} coap_dtls_cpsk_info_t;
/**
* Identity Hint Validation callback that can be set up by
* coap_new_client_session_psk2().
* Invoked when libcoap has done the validation checks at the TLS level,
* but the application needs to check that the Identity Hint is allowed,
* and thus needs to use the appropriate PSK information for the Identity
* Hint for the (D)TLS session.
* Note: Identity Hint is not supported in (D)TLS1.3.
*
* @param hint The server provided Identity Hint
* @param coap_session The CoAP session associated with the Identity Hint
* @param arg The same as was passed into coap_new_client_session_psk2()
* in setup_data->ih_call_back_arg
*
* @return New coap_dtls_cpsk_info_t object or @c NULL on error.
*/
typedef const coap_dtls_cpsk_info_t *(*coap_dtls_ih_callback_t)(
coap_str_const_t *hint,
coap_session_t *coap_session,
void *arg);
#define COAP_DTLS_CPSK_SETUP_VERSION 1 /**< Latest CPSK setup version */
/**
* The structure used for defining the Client PSK setup data to be used.
*/
typedef struct coap_dtls_cpsk_t {
uint8_t version; /** Set to COAP_DTLS_CPSK_SETUP_VERSION
to support this version of the struct */
/* Options to enable different TLS functionality in libcoap */
uint8_t reserved[7]; /**< Reserved - must be set to 0 for
future compatibility */
/* Size of 7 chosen to align to next
* parameter, so if newly defined option
* it can use one of the reserverd slot so
* no need to change
* COAP_DTLS_CPSK_SETUP_VERSION and just
* decrement the reserved[] count.
*/
/** Identity Hint check callback function.
* If not NULL, is called when the Identity Hint (TLS1.2 or earlier) is
* provided by the server.
* The appropriate Identity and Pre-shared Key to use can then be returned.
*/
coap_dtls_ih_callback_t validate_ih_call_back;
void *ih_call_back_arg; /**< Passed in to the Identity Hint callback
function */
char* client_sni; /**< If not NULL, SNI to use in client TLS setup.
Owned by the client app and must remain valid
during the call to coap_new_client_session_psk2()
Note: Not supported by TinyDTLS. */
coap_dtls_cpsk_info_t psk_info; /**< Client PSK definition */
} coap_dtls_cpsk_t;
/**
* The structure that holds the Server Pre-Shared Key and Identity
* Hint information.
*/
typedef struct coap_dtls_spsk_info_t {
coap_bin_const_t hint;
coap_bin_const_t key;
} coap_dtls_spsk_info_t;
/**
* Identity Validation callback that can be set up by
* coap_context_set_psk2().
* Invoked when libcoap has done the validation checks at the TLS level,
* but the application needs to check that the Identity is allowed,
* and needs to use the appropriate Pre-Shared Key for the (D)TLS session.
*
* @param identity The client provided Identity
* @param coap_session The CoAP session associated with the Identity Hint
* @param arg The value as passed into coap_context_set_psk2()
* in setup_data->id_call_back_arg
*
* @return New coap_bin_const_t object containing the Pre-Shared Key or
@c NULL on error.
* Note: This information will be duplicated into an internal
* structure.
*/
typedef const coap_bin_const_t *(*coap_dtls_id_callback_t)(
coap_bin_const_t *identity,
coap_session_t *coap_session,
void *arg);
/**
* PSK SNI callback that can be set up by coap_context_set_psk2().
* Invoked when libcoap has done the validation checks at the TLS level
* and the application needs to:-
* a) check that the SNI is allowed
* b) provide the appropriate PSK information for the (D)TLS session.
*
* @param sni The client provided SNI
* @param coap_session The CoAP session associated with the SNI
* @param arg The same as was passed into coap_context_set_psk2()
* in setup_data->sni_call_back_arg
*
* @return New coap_dtls_spsk_info_t object or @c NULL on error.
*/
typedef const coap_dtls_spsk_info_t *(*coap_dtls_psk_sni_callback_t)(
const char *sni,
coap_session_t *coap_session,
void *arg);
#define COAP_DTLS_SPSK_SETUP_VERSION 1 /**< Latest SPSK setup version */
/**
* The structure used for defining the Server PSK setup data to be used.
*/
typedef struct coap_dtls_spsk_t {
uint8_t version; /** Set to COAP_DTLS_SPSK_SETUP_VERSION
to support this version of the struct */
/* Options to enable different TLS functionality in libcoap */
uint8_t reserved[7]; /**< Reserved - must be set to 0 for
future compatibility */
/* Size of 7 chosen to align to next
* parameter, so if newly defined option
* it can use one of the reserverd slot so
* no need to change
* COAP_DTLS_SPSK_SETUP_VERSION and just
* decrement the reserved[] count.
*/
/** Identity check callback function.
* If not @p NULL, is called when the Identity is provided by the client.
* The appropriate Pre-Shared Key to use can then be returned.
*/
coap_dtls_id_callback_t validate_id_call_back;
void *id_call_back_arg; /**< Passed in to the Identity callback function */
/** SNI check callback function.
* If not @p NULL, called if the SNI is not previously seen and prior to
* sending PSK information back to the client so that the appropriate
* PSK information can be used based on the requesting SNI.
*/
coap_dtls_psk_sni_callback_t validate_sni_call_back;
void *sni_call_back_arg; /**< Passed in to the SNI callback function */
coap_dtls_spsk_info_t psk_info; /**< Server PSK definition */
} coap_dtls_spsk_t;
/** @} */
/**
* @ingroup logging
* Sets the (D)TLS logging level to the specified @p level.
* Note: coap_log_level() will influence output if at a specified level.
*
* @param level The logging level to use - LOG_*
*/
void coap_dtls_set_log_level(int level);
/**
* @ingroup logging
* Get the current (D)TLS logging.
*
* @return The current log level (one of LOG_*).
*/
int coap_dtls_get_log_level(void);
#endif /* COAP_DTLS_H */