• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * coap_dtls.h -- (Datagram) Transport Layer Support for libcoap
3  *
4  * Copyright (C) 2016 Olaf Bergmann <bergmann@tzi.org>
5  * Copyright (C) 2017 Jean-Claude Michelou <jcm@spinetix.com>
6  *
7  * SPDX-License-Identifier: BSD-2-Clause
8  *
9  * This file is part of the CoAP library libcoap. Please see README for terms
10  * of use.
11  */
12 
13 /**
14  * @file coap_dtls.h
15  * @brief CoAP DTLS support
16  */
17 
18 #ifndef COAP_DTLS_H_
19 #define COAP_DTLS_H_
20 
21 #include "coap_time.h"
22 #include "coap_str.h"
23 
24 /**
25  * @ingroup application_api
26  * @defgroup dtls DTLS Support
27  * API for interfacing with DTLS libraries.
28  * @{
29  */
30 
31 typedef struct coap_dtls_pki_t coap_dtls_pki_t;
32 
33 #ifndef COAP_DTLS_HINT_LENGTH
34 #define COAP_DTLS_HINT_LENGTH 128
35 #endif
36 #ifndef COAP_DTLS_MAX_PSK_IDENTITY
37 #define COAP_DTLS_MAX_PSK_IDENTITY 64
38 #endif
39 #ifndef COAP_DTLS_MAX_PSK
40 #define COAP_DTLS_MAX_PSK 64
41 #endif
42 
43 typedef enum coap_dtls_role_t {
44   COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */
45   COAP_DTLS_ROLE_SERVER  /**< Internal function invoked for server */
46 } coap_dtls_role_t;
47 
48 #define COAP_DTLS_RPK_CERT_CN "RPK"
49 
50 /**
51  * Check whether DTLS is available.
52  *
53  * @return @c 1 if support for DTLS is available, or @c 0 otherwise.
54  */
55 int coap_dtls_is_supported(void);
56 
57 /**
58  * Check whether TLS is available.
59  *
60  * @return @c 1 if support for TLS is available, or @c 0 otherwise.
61  */
62 int coap_tls_is_supported(void);
63 
64 /**
65  * Check whether (D)TLS PSK is available.
66  *
67  * @return @c 1 if support for (D)TLS PSK is available, or @c 0 otherwise.
68  */
69 int coap_dtls_psk_is_supported(void);
70 
71 /**
72  * Check whether (D)TLS PKI is available.
73  *
74  * @return @c 1 if support for (D)TLS PKI is available, or @c 0 otherwise.
75  */
76 int coap_dtls_pki_is_supported(void);
77 
78 /**
79  * Check whether (D)TLS PKCS11 is available.
80  *
81  * @return @c 1 if support for (D)TLS PKCS11 is available, or @c 0 otherwise.
82  */
83 int coap_dtls_pkcs11_is_supported(void);
84 
85 /**
86  * Check whether (D)TLS RPK is available.
87  *
88  * @return @c 1 if support for (D)TLS RPK is available, or @c 0 otherwise.
89  */
90 int coap_dtls_rpk_is_supported(void);
91 
92 typedef enum coap_tls_library_t {
93   COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */
94   COAP_TLS_LIBRARY_TINYDTLS,  /**< Using TinyDTLS library */
95   COAP_TLS_LIBRARY_OPENSSL,   /**< Using OpenSSL library */
96   COAP_TLS_LIBRARY_GNUTLS,    /**< Using GnuTLS library */
97   COAP_TLS_LIBRARY_MBEDTLS,   /**< Using Mbed TLS library */
98 } coap_tls_library_t;
99 
100 /**
101  * The structure used for returning the underlying (D)TLS library
102  * information.
103  */
104 typedef struct coap_tls_version_t {
105   uint64_t version; /**< (D)TLS runtime Library Version */
106   coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */
107   uint64_t built_version; /**< (D)TLS Built against Library Version */
108 } coap_tls_version_t;
109 
110 /**
111  * Determine the type and version of the underlying (D)TLS library.
112  *
113  * @return The version and type of library libcoap was compiled against.
114  */
115 coap_tls_version_t *coap_get_tls_library_version(void);
116 
117 /**
118  * Additional Security setup handler that can be set up by
119  * coap_context_set_pki().
120  * Invoked when libcoap has done the validation checks at the TLS level,
121  * but the application needs to do some additional checks/changes/updates.
122  *
123  * @param tls_session The security session definition - e.g. SSL * for OpenSSL.
124  *                    NULL if server callback.
125  *                    This will be dependent on the underlying TLS library -
126  *                    see coap_get_tls_library_version()
127  * @param setup_data A structure containing setup data originally passed into
128  *                   coap_context_set_pki() or coap_new_client_session_pki().
129  *
130  * @return @c 1 if successful, else @c 0.
131  */
132 typedef int (*coap_dtls_security_setup_t)(void *tls_session,
133                                           coap_dtls_pki_t *setup_data);
134 
135 /**
136  * CN Validation callback that can be set up by coap_context_set_pki().
137  * Invoked when libcoap has done the validation checks at the TLS level,
138  * but the application needs to check that the CN is allowed.
139  * CN is the SubjectAltName in the cert, if not present, then the leftmost
140  * Common Name (CN) component of the subject name.
141  * NOTE: If using RPK, then the Public Key does not contain a CN, but the
142  * content of COAP_DTLS_RPK_CERT_CN is presented for the @p cn parameter.
143  *
144  * @param cn  The determined CN from the certificate
145  * @param asn1_public_cert  The ASN.1 DER encoded X.509 certificate
146  * @param asn1_length  The ASN.1 length
147  * @param coap_session  The CoAP session associated with the certificate update
148  * @param depth  Depth in cert chain.  If 0, then client cert, else a CA
149  * @param validated  TLS layer can find no issues if 1
150  * @param arg  The same as was passed into coap_context_set_pki()
151  *             in setup_data->cn_call_back_arg
152  *
153  * @return @c 1 if accepted, else @c 0 if to be rejected.
154  */
155 typedef int (*coap_dtls_cn_callback_t)(const char *cn,
156                                        const uint8_t *asn1_public_cert,
157                                        size_t asn1_length,
158                                        coap_session_t *coap_session,
159                                        unsigned int depth,
160                                        int validated,
161                                        void *arg);
162 
163 /**
164  * The enum used for determining the provided PKI ASN.1 (DER) Private Key
165  * formats.
166  */
167 typedef enum coap_asn1_privatekey_type_t {
168   COAP_ASN1_PKEY_NONE,     /**< NONE */
169   COAP_ASN1_PKEY_RSA,      /**< RSA type */
170   COAP_ASN1_PKEY_RSA2,     /**< RSA2 type */
171   COAP_ASN1_PKEY_DSA,      /**< DSA type */
172   COAP_ASN1_PKEY_DSA1,     /**< DSA1 type */
173   COAP_ASN1_PKEY_DSA2,     /**< DSA2 type */
174   COAP_ASN1_PKEY_DSA3,     /**< DSA3 type */
175   COAP_ASN1_PKEY_DSA4,     /**< DSA4 type */
176   COAP_ASN1_PKEY_DH,       /**< DH type */
177   COAP_ASN1_PKEY_DHX,      /**< DHX type */
178   COAP_ASN1_PKEY_EC,       /**< EC type */
179   COAP_ASN1_PKEY_HMAC,     /**< HMAC type */
180   COAP_ASN1_PKEY_CMAC,     /**< CMAC type */
181   COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */
182   COAP_ASN1_PKEY_HKDF      /**< HKDF type */
183 } coap_asn1_privatekey_type_t;
184 
185 /**
186  * The enum used for determining the PKI key formats.
187  */
188 typedef enum coap_pki_key_t {
189   COAP_PKI_KEY_PEM = 0,        /**< The PKI key type is PEM file */
190   COAP_PKI_KEY_ASN1,           /**< The PKI key type is ASN.1 (DER) buffer */
191   COAP_PKI_KEY_PEM_BUF,        /**< The PKI key type is PEM buffer */
192   COAP_PKI_KEY_PKCS11,         /**< The PKI key type is PKCS11 (DER) */
193 } coap_pki_key_t;
194 
195 /**
196  * The structure that holds the PKI PEM definitions.
197  */
198 typedef struct coap_pki_key_pem_t {
199   const char *ca_file;       /**< File location of Common CA in PEM format */
200   const char *public_cert;   /**< File location of Public Cert */
201   const char *private_key;   /**< File location of Private Key in PEM format */
202 } coap_pki_key_pem_t;
203 
204 /**
205  * The structure that holds the PKI PEM buffer definitions.
206  * The certificates and private key data must be in PEM format.
207  *
208  * Note:  The Certs and Key should be NULL terminated strings for
209  * performance reasons (to save a potential buffer copy) and the length include
210  * this NULL terminator. It is not a requirement to have the NULL terminator
211  * though and the length must then reflect the actual data size.
212  */
213 typedef struct coap_pki_key_pem_buf_t {
214   const uint8_t *ca_cert;     /**< PEM buffer Common CA Cert */
215   const uint8_t *public_cert; /**< PEM buffer Public Cert, or Public Key if RPK */
216   const uint8_t *private_key; /**< PEM buffer Private Key
217                                   If RPK and 'EC PRIVATE KEY' this can be used
218                                   for both the public_cert and private_key */
219   size_t ca_cert_len;         /**< PEM buffer CA Cert length */
220   size_t public_cert_len;     /**< PEM buffer Public Cert length */
221   size_t private_key_len;     /**< PEM buffer Private Key length */
222 } coap_pki_key_pem_buf_t;
223 
224 /**
225  * The structure that holds the PKI ASN.1 (DER) definitions.
226  */
227 typedef struct coap_pki_key_asn1_t {
228   const uint8_t *ca_cert;     /**< ASN1 (DER) Common CA Cert */
229   const uint8_t *public_cert; /**< ASN1 (DER) Public Cert, or Public Key if RPK */
230   const uint8_t *private_key; /**< ASN1 (DER) Private Key */
231   size_t ca_cert_len;         /**< ASN1 CA Cert length */
232   size_t public_cert_len;     /**< ASN1 Public Cert length */
233   size_t private_key_len;     /**< ASN1 Private Key length */
234   coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */
235 } coap_pki_key_asn1_t;
236 
237 /**
238  * The structure that holds the PKI PKCS11 definitions.
239  */
240 typedef struct coap_pki_key_pkcs11_t {
241   const char *ca;            /**< pkcs11: URI for Common CA Certificate */
242   const char *public_cert;   /**< pkcs11: URI for Public Cert */
243   const char *private_key;   /**< pkcs11: URI for Private Key */
244   const char *user_pin;      /**< User pin to access PKCS11.  If NULL, then
245                                   pin-value= parameter must be set in
246                                   pkcs11: URI as a query. */
247 } coap_pki_key_pkcs11_t;
248 
249 /**
250  * The structure that holds the PKI key information.
251  */
252 typedef struct coap_dtls_key_t {
253   coap_pki_key_t key_type;          /**< key format type */
254   union {
255     coap_pki_key_pem_t pem;          /**< for PEM file keys */
256     coap_pki_key_pem_buf_t pem_buf;  /**< for PEM memory keys */
257     coap_pki_key_asn1_t asn1;        /**< for ASN.1 (DER) memory keys */
258     coap_pki_key_pkcs11_t pkcs11;    /**< for PKCS11 keys */
259   } key;
260 } coap_dtls_key_t;
261 
262 /**
263  * Server Name Indication (SNI) Validation callback that can be set up by
264  * coap_context_set_pki().
265  * Invoked if the SNI is not previously seen and prior to sending a certificate
266  * set back to the client so that the appropriate certificate set can be used
267  * based on the requesting SNI.
268  *
269  * @param sni  The requested SNI
270  * @param arg  The same as was passed into coap_context_set_pki()
271  *             in setup_data->sni_call_back_arg
272  *
273  * @return New set of certificates to use, or @c NULL if SNI is to be rejected.
274  */
275 typedef coap_dtls_key_t *(*coap_dtls_pki_sni_callback_t)(const char *sni,
276                                                          void *arg);
277 
278 
279 #define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */
280 
281 /**
282  * The structure used for defining the PKI setup data to be used.
283  */
284 struct coap_dtls_pki_t {
285   uint8_t version; /** Set to COAP_DTLS_PKI_SETUP_VERSION
286                        to support this version of the struct */
287 
288   /* Options to enable different TLS functionality in libcoap */
289   uint8_t verify_peer_cert;        /**< 1 if peer cert is to be verified */
290   uint8_t check_common_ca;         /**< 1 if peer cert is to be signed by
291                                     * the same CA as the local cert */
292   uint8_t allow_self_signed;       /**< 1 if self-signed certs are allowed.
293                                     *     Ignored if check_common_ca set */
294   uint8_t allow_expired_certs;     /**< 1 if expired certs are allowed */
295   uint8_t cert_chain_validation;   /**< 1 if to check cert_chain_verify_depth */
296   uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */
297   uint8_t check_cert_revocation;   /**< 1 if revocation checks wanted */
298   uint8_t allow_no_crl;            /**< 1 ignore if CRL not there */
299   uint8_t allow_expired_crl;       /**< 1 if expired crl is allowed */
300   uint8_t allow_bad_md_hash;      /**< 1 if unsupported MD hashes are allowed */
301   uint8_t allow_short_rsa_length; /**< 1 if small RSA keysizes are allowed */
302   uint8_t is_rpk_not_cert;        /**< 1 is RPK instead of Public Certificate.
303                                    *     If set, PKI key format type cannot be
304                                    *     COAP_PKI_KEY_PEM */
305   uint8_t reserved[3];             /**< Reserved - must be set to 0 for
306                                         future compatibility */
307   /* Size of 3 chosen to align to next
308    * parameter, so if newly defined option
309    * it can use one of the reserved slots so
310    * no need to change
311    * COAP_DTLS_PKI_SETUP_VERSION and just
312    * decrement the reserved[] count.
313    */
314 
315   /** CN check callback function.
316    * If not NULL, is called when the TLS connection has passed the configured
317    * TLS options above for the application to verify if the CN is valid.
318    */
319   coap_dtls_cn_callback_t validate_cn_call_back;
320   void *cn_call_back_arg;  /**< Passed in to the CN callback function */
321 
322   /** SNI check callback function.
323    * If not @p NULL, called if the SNI is not previously seen and prior to
324    * sending a certificate set back to the client so that the appropriate
325    * certificate set can be used based on the requesting SNI.
326    */
327   coap_dtls_pki_sni_callback_t validate_sni_call_back;
328   void *sni_call_back_arg;  /**< Passed in to the sni callback function */
329 
330   /** Additional Security callback handler that is invoked when libcoap has
331    * done the standard, defined validation checks at the TLS level,
332    * If not @p NULL, called from within the TLS Client Hello connection
333    * setup.
334    */
335   coap_dtls_security_setup_t additional_tls_setup_call_back;
336 
337   char *client_sni;    /**<  If not NULL, SNI to use in client TLS setup.
338                              Owned by the client app and must remain valid
339                              during the call to coap_new_client_session_pki() */
340 
341   coap_dtls_key_t pki_key;  /**< PKI key definition */
342 };
343 
344 /**
345  * The structure that holds the Client PSK information.
346  */
347 typedef struct coap_dtls_cpsk_info_t {
348   coap_bin_const_t identity;
349   coap_bin_const_t key;
350 } coap_dtls_cpsk_info_t;
351 
352 /**
353  * Identity Hint Validation callback that can be set up by
354  * coap_new_client_session_psk2().
355  * Invoked when libcoap has done the validation checks at the TLS level,
356  * but the application needs to check that the Identity Hint is allowed,
357  * and thus needs to use the appropriate PSK information for the Identity
358  * Hint for the (D)TLS session.
359  * Note: Identity Hint is not supported in (D)TLS1.3.
360  *
361  * @param hint  The server provided Identity Hint
362  * @param coap_session  The CoAP session associated with the Identity Hint
363  * @param arg  The same as was passed into coap_new_client_session_psk2()
364  *             in setup_data->ih_call_back_arg
365  *
366  * @return New coap_dtls_cpsk_info_t object or @c NULL on error.
367  */
368 typedef const coap_dtls_cpsk_info_t *(*coap_dtls_ih_callback_t)(
369     coap_str_const_t *hint,
370     coap_session_t *coap_session,
371     void *arg);
372 
373 #define COAP_DTLS_CPSK_SETUP_VERSION 1 /**< Latest CPSK setup version */
374 
375 /**
376  * The structure used for defining the Client PSK setup data to be used.
377  */
378 typedef struct coap_dtls_cpsk_t {
379   uint8_t version; /** Set to COAP_DTLS_CPSK_SETUP_VERSION
380                        to support this version of the struct */
381 
382   /* Options to enable different TLS functionality in libcoap */
383   uint8_t reserved[7];             /**< Reserved - must be set to 0 for
384                                         future compatibility */
385   /* Size of 7 chosen to align to next
386    * parameter, so if newly defined option
387    * it can use one of the reserverd slot so
388    * no need to change
389    * COAP_DTLS_CPSK_SETUP_VERSION and just
390    * decrement the reserved[] count.
391    */
392 
393   /** Identity Hint check callback function.
394    * If not NULL, is called when the Identity Hint (TLS1.2 or earlier) is
395    * provided by the server.
396    * The appropriate Identity and Pre-shared Key to use can then be returned.
397    */
398   coap_dtls_ih_callback_t validate_ih_call_back;
399   void *ih_call_back_arg;  /**< Passed in to the Identity Hint callback
400                                 function */
401 
402   char *client_sni;    /**< If not NULL, SNI to use in client TLS setup.
403                             Owned by the client app and must remain valid
404                             during the call to coap_new_client_session_psk2()
405                             Note: Not supported by TinyDTLS. */
406 
407   coap_dtls_cpsk_info_t psk_info;  /**< Client PSK definition */
408 } coap_dtls_cpsk_t;
409 
410 /**
411  * The structure that holds the Server Pre-Shared Key and Identity
412  * Hint information.
413  */
414 typedef struct coap_dtls_spsk_info_t {
415   coap_bin_const_t hint;
416   coap_bin_const_t key;
417 } coap_dtls_spsk_info_t;
418 
419 
420 /**
421  * Identity Validation callback that can be set up by
422  * coap_context_set_psk2().
423  * Invoked when libcoap has done the validation checks at the TLS level,
424  * but the application needs to check that the Identity is allowed,
425  * and needs to use the appropriate Pre-Shared Key for the (D)TLS session.
426  *
427  * @param identity  The client provided Identity
428  * @param coap_session  The CoAP session associated with the Identity Hint
429  * @param arg  The value as passed into coap_context_set_psk2()
430  *             in setup_data->id_call_back_arg
431  *
432  * @return New coap_bin_const_t object containing the Pre-Shared Key or
433            @c NULL on error.
434  *         Note: This information will be duplicated into an internal
435  *               structure.
436  */
437 typedef const coap_bin_const_t *(*coap_dtls_id_callback_t)(
438     coap_bin_const_t *identity,
439     coap_session_t *coap_session,
440     void *arg);
441 /**
442  * PSK SNI callback that can be set up by coap_context_set_psk2().
443  * Invoked when libcoap has done the validation checks at the TLS level
444  * and the application needs to:-
445  * a) check that the SNI is allowed
446  * b) provide the appropriate PSK information for the (D)TLS session.
447  *
448  * @param sni  The client provided SNI
449  * @param coap_session  The CoAP session associated with the SNI
450  * @param arg  The same as was passed into coap_context_set_psk2()
451  *             in setup_data->sni_call_back_arg
452  *
453  * @return New coap_dtls_spsk_info_t object or @c NULL on error.
454  */
455 typedef const coap_dtls_spsk_info_t *(*coap_dtls_psk_sni_callback_t)(
456     const char *sni,
457     coap_session_t *coap_session,
458     void *arg);
459 
460 #define COAP_DTLS_SPSK_SETUP_VERSION 1 /**< Latest SPSK setup version */
461 
462 /**
463  * The structure used for defining the Server PSK setup data to be used.
464  */
465 typedef struct coap_dtls_spsk_t {
466   uint8_t version; /** Set to COAP_DTLS_SPSK_SETUP_VERSION
467                        to support this version of the struct */
468 
469   /* Options to enable different TLS functionality in libcoap */
470   uint8_t reserved[7];             /**< Reserved - must be set to 0 for
471                                         future compatibility */
472   /* Size of 7 chosen to align to next
473    * parameter, so if newly defined option
474    * it can use one of the reserverd slot so
475    * no need to change
476    * COAP_DTLS_SPSK_SETUP_VERSION and just
477    * decrement the reserved[] count.
478    */
479 
480   /** Identity check callback function.
481    * If not @p NULL, is called when the Identity is provided by the client.
482    * The appropriate Pre-Shared Key to use can then be returned.
483    */
484   coap_dtls_id_callback_t validate_id_call_back;
485   void *id_call_back_arg;  /**< Passed in to the Identity callback function */
486 
487   /** SNI check callback function.
488    * If not @p NULL, called if the SNI is not previously seen and prior to
489    * sending PSK information back to the client so that the appropriate
490    * PSK information can be used based on the requesting SNI.
491    */
492   coap_dtls_psk_sni_callback_t validate_sni_call_back;
493   void *sni_call_back_arg;  /**< Passed in to the SNI callback function */
494 
495   coap_dtls_spsk_info_t psk_info;  /**< Server PSK definition */
496 } coap_dtls_spsk_t;
497 
498 
499 /** @} */
500 
501 #endif /* COAP_DTLS_H */
502