• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// -*- mode:doc; -*-
2// vim: set syntax=asciidoc tw=0
3
4coap_encryption(3)
5===================
6:doctype: manpage
7:man source:   coap_encryption
8:man version:  @PACKAGE_VERSION@
9:man manual:   libcoap Manual
10
11NAME
12----
13coap_encryption,
14coap_dtls_cpsk_t,
15coap_dtls_spsk_t,
16coap_dtls_pki_t
17- Work with CoAP TLS/DTLS
18
19SYNOPSIS
20--------
21*#include <coap@LIBCOAP_API_VERSION@/coap.h>*
22
23*struct coap_dtls_cpsk_t;*
24
25*struct coap_dtls_spsk_t;*
26
27*struct coap_dtls_pki_t;*
28
29For specific (D)TLS library support, link with
30*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*,
31*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls*
32or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*.   Otherwise, link with
33*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support.
34
35DESCRIPTION
36-----------
37This man page focuses on setting up CoAP to use encryption.
38
39When the libcoap library was built, it will have been compiled using a
40specific underlying TLS implementation type (e.g. https://www.openssl.org[OpenSSL],
41https://www.gnutls.org[GnuTLS],
42https://www.trustedfirmware.org/projects/mbed-tls/[Mbed TLS],
43https://github.com/eclipse/tinydtls[TinyDTLS] or noTLS).
44When the libcoap library is linked into an application, it is possible
45that the application needs to dynamically determine whether DTLS or TLS is
46supported, what type of TLS implementation libcoap was compiled with, as well
47as detect what is the version of the currently loaded TLS library.
48
49*NOTE:* If OpenSSL is being used, then the minimum supported OpenSSL library
50version is 1.1.0.
51
52*NOTE:* If GnuTLS is being used, then the minimum GnuTLS library version is
533.3.0.
54
55*NOTE:* If Mbed TLS is being used, then the minimum Mbed TLS library version is
562.7.10.
57
58*NOTE:* If GnuTLS is going to interoperate with TinyDTLS, then a minimum
59revision of GnuTLS 3.5.5 which supports CCM algorithms is required
60by TinyDTLS as TinyDTLS currently only supports CCM.
61
62*NOTE:* For Raw Public Key support, GnuTLS library version must be 3.6.6 or
63later. TinyDTLS only supports TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, curve
64secp256r1 and hash SHA-256.  There currently is no OpenSSL or Mbed TLS RPK support
65(respective library limitations).
66
67Network traffic can be un-encrypted or encrypted with libcoap if there is an
68underlying TLS library.
69
70If TLS is going to be used for encrypting the network traffic, then the TLS
71information for Pre-Shared Keys (PSK), Public Key Infrastructure (PKI) or
72Raw Public Key (RPK) needs to be configured before any network traffic starts
73to flow. For Servers, this has to be done before the Endpoint is created,
74for Clients, this is done during the Client Session set up.
75
76For Servers, all the encryption information is held internally by the TLS
77Context level and the CoAP Context level as the Server is listening for new
78incoming traffic based on the Endpoint definition.  The TLS and CoAP session
79will not get built until the new traffic starts, which is done by the libcoap
80library, with the session having a reference count of 1.
81
82For Clients, all the encryption information will be held internally by the TLS
83Context and/or TLS Session level and internally by the CoAP Session level.
84
85In principle the set-up sequence for CoAP Servers looks like
86----
87coap_new_context()
88coap_context_set_pki_root_cas() - if the root CAs need to be updated and PKI
89coap_context_set_pki() and/or coap_context_set_psk2() - if encryption is required
90coap_new_endpoint()
91----
92
93Multiple endpoints can be set up per Context, each listening for a new traffic
94flow with different TCP/UDP protocols, TLS protocols, port numbers etc. When a
95new traffic flow is started, then the CoAP library will create and start a new
96server session.
97
98In principle the set-up sequence for CoAP Clients looks like
99----
100coap_new_context()
101coap_context_set_pki_root_cas() - if the root CAs need to be updated and PKI
102coap_new_client_session(), coap_new_client_session_pki() or coap_new_client_session_psk2()
103----
104
105Multiple client sessions are supported per Context.
106
107Due to the nature of TLS, there are Callbacks that are invoked as the TLS
108session negotiates encryption algorithms, encryption keys etc.
109Where possible, the CoAP layer handles all this automatically based on
110different configuration options passed in by the *coap_context_set_pki*(),
111*coap_new_client_session_pki*(), *coap_context_set_psk2*() and
112*coap_new_client_session_psk2*() functions.
113
114PSK CLIENT INFORMATION
115----------------------
116
117For Client PSK setup, the required information needs to be provided in the setup
118calls with optional application callbacks defined to update the Identity and
119PSK. Initially, the Client has to provide an Identity and a Pre-Shared Key.
120
121Libcoap will put the Identity and Pre-Shared Key as appropriate into the TLS
122environment.
123
124*SECTION: PSK Client: coap_dtls_cpsk_t*
125[source, c]
126----
127typedef struct coap_dtls_cpsk_t {
128  uint8_t version; /** Set to COAP_DTLS_CPSK_SETUP_VERSION
129                       to support the version of the struct */
130
131  /* Options to enable different TLS functionality in libcoap */
132  uint8_t reserved[7];             /* Reserved - must be set to 0 for
133                                      future compatibility */
134
135  /** Identity Hint check callback function.
136   * If not NULL, is called when the Identity Hint (TLS1.2 or earlier) is
137   * provided by the server.
138   * The appropriate Identity and Pre-Shared Key to use can then be returned.
139   */
140  coap_dtls_ih_callback_t validate_ih_call_back;
141  void *ih_call_back_arg;  /* Passed in to the Identity Hint callback
142                              function */
143
144  char* client_sni;    /*  If not NULL, SNI to use in client TLS setup.
145                           Owned by the client app and must remain valid
146                           during the call to coap_new_client_session_pki().
147                           Note: Not supported by TinyDTLS. */
148
149  coap_dtls_cpsk_info_t psk_info;  /* Client PSK definition */
150} coap_dtls_cpsk_t;
151----
152
153More detailed explanation of the coap_dtls_cpsk_t structure follows.
154
155*WARNING*: For all the parameter definitions that are pointers to other
156locations, these locations must remain valid during the lifetime of all the
157underlying TLS sessions that are, or will get created based on this PSK
158definition.
159
160*SECTION: PSK Client: coap_dtls_cpsk_t: Version*
161[source, c]
162----
163#define COAP_DTLS_CPSK_SETUP_VERSION 1 /**< Latest CPSK setup version */
164----
165
166*version* is set to COAP_DTLS_CPSK_SETUP_VERSION.  This will then allow
167support for different versions of the coap_dtls_cpsk_t structure in the future.
168
169*SECTION: PSK Client: coap_dtls_cpsk_t: Reserved*
170
171*reserved* All must be set to 0.  Future functionality updates will make use of
172these reserved definitions.
173
174*SECTION: PSK Client: coap_dtls_cpsk_t: Identity Hint Callback*
175[source, c]
176----
177/**
178 * Identity Hint Validation callback that can be set up by
179 * coap_new_client_session_psk2().
180 * Invoked when libcoap has done the validation checks at the TLS level,
181 * but the application needs to check that the Identity Hint is allowed, and
182 * needs to use the appropriate PSK information for the (D)TLS session.
183 * Note: Identity Hint is not supported in (D)TLS1.3.
184 *
185 * @param hint  The server provided Identity Hint
186 * @param coap_session  The CoAP session associated with the Identity Hint
187 * @param arg  The same as was passed into coap_new_client_session_psk2()
188 *             in setup_data->ih_call_back_arg
189 *
190 * @return New coap_dtls_cpsk_info_t object or @c NULL on error.
191 */
192typedef const coap_dtls_cpsk_info_t *(*coap_dtls_ih_callback_t)(
193                                coap_str_const_t *hint,
194                                coap_session_t *coap_session,
195                                void *arg);
196----
197
198*validate_ih_call_back* points to an application provided Identity Hint callback
199function or NULL. The application can make use of this Identity Hint information
200to decide what Identity and Pre-Shared Key should be used for this session.
201The Callback returns the new coap_dtls_cpsk_info_t on success,
202or NULL if the Identity Hint is unacceptable.
203
204*NOTE:* The Server may not provide a hint, or a zero length hint to indicate
205there is no hint.  In this case the initially provided Identity and
206Pre-Shared Key should be used.
207
208*ih_call_back_arg* points to a user defined set of data that will get passed
209in to the validate_ih_call_back() function's arg parameter and can be used by
210that function.  An example would be a set of Identity Hints that map into new
211Identity / Pre-Shared Key to use.
212
213*SECTION: PSK Client: coap_dtls_cpsk_t: Subject Name Indicator (SNI) Definition*
214
215*client_sni* points to the SNI name that will be added in as a TLS extension,
216if not NULL.  This typically is the DNS name of the server that the client is
217trying to contact.  The server is then able to decide, based on the name in the
218SNI extension, whether, for example, a different Hint and/or Pre-Shared Key is
219to be used.
220
221*NOTE:* Not supported by TinyDTLS.
222
223*SECTION: PSK Client: coap_dtls_cpsk_t: PSK Client Definitions*
224[source, c]
225----
226typedef struct coap_dtls_cpsk_info_t {
227  coap_bin_const_t identity; /* The Identity */
228  coap_bin_const_t key;      /* The Pre-Shared Key */
229} coap_dtls_cpsk_info_t;
230----
231
232*identity* defines the Identity to use.
233
234*key* defines the Pre-Shared Key to use
235
236PSK SERVER INFORMATION
237----------------------
238
239For PSK setup, the required information needs to be provided in the setup
240calls with optional application Callbacks defined to update the Identity Hint
241and Pre-SHared Key. Initially, the Server has to provided with an (optional)
242Identity Hint and a (required) Pre-Shared Key.
243
244Libcoap will put the Hint and Pre-Shared Key as appropriate into the TLS
245environment.
246
247*SECTION: PSK Server: coap_dtls_spsk_t*
248[source, c]
249----
250typedef struct coap_dtls_spsk_t {
251  uint8_t version; /** Set to COAP_DTLS_SPSK_SETUP_VERSION
252                       to support the version of the struct */
253
254  /* Options to enable different TLS functionality in libcoap */
255  uint8_t reserved[7];             /* Reserved - must be set to 0 for
256                                      future compatibility */
257
258  /** Identity check callback function.
259   * If not @p NULL, is called when the Identity is provided by the client.
260   *  The appropriate Pre-Shared Key to use can then be returned.
261   */
262  coap_dtls_id_callback_t validate_id_call_back;
263  void *id_call_back_arg;  /* Passed in to the Identity callback function */
264
265  /** SNI check callback function.
266   * If not @p NULL, called if the SNI is not previously seen and exexuted
267   * prior to sending an Identity Hint back to the client so that the
268   * appropriate PSK information can be used based on the requesting SNI.
269   */
270  coap_dtls_psk_sni_callback_t validate_sni_call_back;
271  void *sni_call_back_arg;  /* Passed in to the SNI callback function */
272
273  coap_dtls_spsk_info_t psk_info;  /* Server PSK definition */
274} coap_dtls_spsk_t;
275----
276
277More detailed explanation of the coap_dtls_spsk_t structure follows.
278
279*WARNING*: For all the parameter definitions that are pointers to other
280locations, these locations must remain valid during the lifetime of all the
281underlying TLS sessions that are, or will get created based on this PSK
282definition.
283
284*SECTION: PSK Server: coap_dtls_spsk_t: Version*
285[source, c]
286----
287#define COAP_DTLS_SPSK_SETUP_VERSION 1 /**< Latest SPSK setup version */
288----
289
290*version* is set to COAP_DTLS_SPSK_SETUP_VERSION.  This will then allow
291support for different versions of the coap_dtls_spsk_t structure in the future.
292
293*SECTION: PSK Server: coap_dtls_spsk_t: Reserved*
294
295*reserved* All must be set to 0.  Future functionality updates will make use of
296these reserved definitions.
297
298*SECTION: PSK Server: coap_dtls_spsk_t: Identity Validation Callback*
299[source, c]
300----
301/**
302 * Identity Validation callback that can be set up by
303 * coap_context_set_psk2().
304 * Invoked when libcoap has done the validation checks at the TLS level,
305 * but the application needs to check that the Identity is allowed, and
306 * needs to use the appropriate Pre-Shared Key for the (D)TLS session.
307 *
308 * @param identity  The client provided Identity (should be NULL terminated)
309 * @param coap_session  The CoAP session associated with the Identity Hint
310 * @param arg  The same as was passed into coap_context_set_psk2()
311 *             in setup_data->id_call_back_arg
312 *
313 * @return New coap_bin_const_t Pre-Shared Key object or @c NULL on error.
314 */
315typedef const coap_bin_const_t *(*coap_dtls_id_callback_t)(
316                                 coap_bin_const_t *identity,
317                                 coap_session_t *coap_session,
318                                 void *arg);
319----
320
321*WARNING:* If both *validate_id_call_back* and *validate_sni_call_back* are
322defined, validate_id_call_back() is invoked after validate_sni_call_back(),
323and so if the Pre-Shared Key is changed in validate_sni_call_back(),
324validate_id_call_back() needs to be sure that the appropriate Pre-Shared Key
325is provided.
326
327*validate_id_call_back* points to an application provided Identity callback
328function or NULL. The application can make use of this Identity information
329to decide what PSK should be used for this session.
330The Callback returns the new coap_bin_const_t Pre-Shared Key on success,
331or NULL if the Identity is unacceptable.
332
333*NOTE:* The Client may be using a binary Identity that contains an embedded
334zero. However OpenSSL and GnuTLS do not currently support this.
335
336*id_call_back_arg* points to a user defined set of data that will get passed
337in to the validate_id_call_back() function and can be used by that function.
338An example would be a set of Identities that map into new Pre-Shared Keys
339to use.
340
341*SECTION: PSK Server: coap_dtls_spsk_t: Subject Name Identifier (SNI) Callback*
342[source, c]
343----
344/**
345 * PSK SNI callback that can be set up by coap_context_set_psk2().
346 * Invoked when libcoap has done the validation checks at the TLS level,
347 * but the application needs to check that the SNI is allowed, and needs
348 * to use the appropriate PSK information for the (D)TLS session.
349 *
350 * @param sni  The client provided SNI
351 * @param coap_session  The CoAP session associated with the SNI
352 * @param arg  The same as was passed into coap_new_client_session_psk2()
353 *             in setup_data->sni_call_back_arg
354 *
355 * @return New coap_dtls_spsk_info_t object or @c NULL on error.
356 */
357typedef const coap_dtls_spsk_info_t *(*coap_dtls_psk_sni_callback_t)(
358                                 const char *sni,
359                                 coap_session_t *coap_session,
360                                 void *arg);
361----
362
363*validate_sni_call_back* points to an application provided SNI callback
364checking function or NULL. The application can make use of this SNI information
365to decide whether the SNI is valid, and hence what new Hint and Pre-Shared Key
366to use.
367Thus it is possible for the coap server to host multiple domains with
368different Hints and PSKs allocated to each SNI domain.
369The Callback returns a coap_dtls_spsk_info_t pointer to the Hint and
370Pre-Shared Key to use for this SNI, or NULL if the connection is to get
371rejected.  Libcoap remembers the association between a specific SNI and Hint +
372Pre-Shared Key set and will only invoke this callback if the SNI is unknown.
373
374*NOTE:* Not supported by TinyDTLS.
375
376*sni_call_back_arg* points to a user defined set of data that will get passed
377in to the validate_sni_call_back() function and can be used by that function.
378An example would be a set of SNIs that are allowed with their matching
379Hint + Pre-Shared Key sets.
380
381*SECTION: PSK Server: coap_dtls_spsk_t: PSK Information Definitions*
382[source, c]
383----
384typedef struct coap_dtls_spsk_info_t {
385  coap_bin_const_t hint; /* The identity hint to use */
386  coap_bin_const_t key;  /* The Pre-Shared Key to use */
387} coap_dtls_spsk_info_t;
388----
389
390*identity* defines the Identity Hint to use.
391
392*key* defines the Pre-Shared Key to use
393
394PKI/RPK CLIENT AND SERVER INFORMATION
395-------------------------------------
396
397For PKI or RPK setup, if the libcoap PKI/RPK configuration options do not
398handle a specific requirement as defined by the available options, then an
399application defined Callback can called to do the additional specific checks.
400
401The information passed to this Application Callback will be the
402TLS session (as well the configuration information), but the structures
403containing this information will be different as they will be based on the
404underlying TLS library type. coap_get_tls_library_version() is provided to help
405here.
406
407Libcoap will add in the defined Certificate (or Public Key), Private Key and
408CA Certificate into the TLS environment.  The CA Certificate is also added
409in to the list of valid CAs for Certificate checking.
410
411The internal Callbacks (and optionally the Application Callback) will then
412check the required information as defined in the coap_dtls_pki_t described
413below.
414
415*SECTION: PKI/RPK: coap_dtls_pki_t*
416[source, c]
417----
418typedef struct coap_dtls_pki_t {
419  uint8_t version;            /* COAP_DTLS_PKI_SETUP_VERSION */
420
421  /* Options to enable different TLS functionality in libcoap */
422  uint8_t verify_peer_cert;         /* 1 if peer cert is to be verified */
423  uint8_t check_common_ca;          /* 1 if peer cert is to be signed by
424                                     * the same CA as the local cert */
425  uint8_t allow_self_signed;        /* 1 if self-signed certs are allowed */
426  uint8_t allow_self_signed;        /* 1 if self-signed certs are allowed.
427                                     * Ignored if check_common_ca set */
428  uint8_t allow_expired_certs;      /* 1 if expired certs are allowed */
429  uint8_t cert_chain_validation;    /* 1 if to check cert_chain_verify_depth */
430  uint8_t cert_chain_verify_depth;  /* recommended depth is 3 */
431  uint8_t check_cert_revocation;    /* 1 if revocation checks wanted */
432  uint8_t allow_no_crl;             /* 1 ignore if CRL not there */
433  uint8_t allow_expired_crl;        /* 1 if expired crl is allowed */
434  uint8_t allow_bad_md_hash;        /* 1 if unsupported MD hashes are allowed */
435  uint8_t allow_short_rsa_length;   /* 1 if small RSA keysizes are allowed */
436  uint8_t is_rpk_not_cert;          /* 1 is RPK instead of Public Certificate.
437                                     *   If set, PKI key format type cannot be
438                                     *   COAP_PKI_KEY_PEM */
439  uint8_t reserved[3];              /* Reserved - must be set to 0 for
440                                       future compatibility */
441
442  /** CN check callback function
443   * If not NULL, is called when the TLS connection has passed the configured
444   * TLS options above for the application to verify if the CN is valid.
445   */
446  coap_dtls_cn_callback_t validate_cn_call_back;
447  void *cn_call_back_arg;  /* Passed in to the CN callback function */
448
449  /** SNI check callback function
450   * If not NULL, called if the SNI is not previously seen and prior to sending
451   * a certificate set back to the client so that the appropriate certificate
452   * set can be used based on the requesting SNI.
453   */
454  coap_dtls_sni_callback_t validate_sni_call_back;
455  void *sni_call_back_arg;  /* Passed in to the SNI callback function */
456
457  /** Additional Security callback handler that is invoked when libcoap has
458   * done the standard, defined validation checks at the TLS level,
459   * If not NULL, called from within the TLS Client Hello connection
460   * setup.
461   */
462  coap_dtls_security_setup_t additional_tls_setup_call_back;
463
464  char* client_sni;       /* If not NULL, SNI to use in client TLS setup.
465                             Owned by the client app and must remain valid
466                             during the call to coap_new_client_session_pki() */
467
468  coap_dtls_key_t pki_key; /* PKI key definition */
469} coap_dtls_pki_t;
470----
471
472More detailed explanation of the coap_dtls_pki_t structure follows.
473
474*WARNING*: For all the parameter definitions that are pointers to other
475locations, these locations must remain valid during the lifetime of all the
476underlying TLS sessions that are, or will get created based on this PKI/RPK
477definition.
478
479The first parameter in each subsection enables/disables the functionality, the
480remaining parameter(s) control what happens when the functionality is
481enabled.
482
483*SECTION: PKI/RPK: coap_dtls_pki_t: Version*
484[source, c]
485----
486#define COAP_DTLS_PKI_SETUP_VERSION 1
487----
488
489*version* is set to COAP_DTLS_PKI_SETUP_VERSION.  This will then allow support
490for different versions of the coap_dtls_pki_t structure in the future.
491
492*SECTION: PKI/RPK: coap_dtls_pki_t: Peer Certificate Checking*
493
494*verify_peer_cert* Set to 1 to check that the peer's certificate is valid if
495provided, else 0. If not set, check_common_ca, allow_self_signed,
496allow_expired_certs, cert_chain_validation, cert_chain_verify_depth,
497check_cert_revocation, allow_no_crl, allow_expired_crl, allow_bad_md_hash
498and allow_short_rsa_length settings are all ignored.
499
500*check_common_ca* Set to 1 to check that the CA that signed the peer's
501certificate is the same CA that signed the local certificate
502else 0.  If set to 1 and *verify_peer_cert* is set to 1, then for the server, a
503list of valid CAs are sent to client.  For the client, the logic will check
504that both the client and server certificates are signed by the same CA.
505
506*allow_self_signed* Set to 1 to allow the peer (or any certificate in the
507certificate chain) to be a self-signed certificate, else 0. If
508*check_common_ca* is set, then a self-signed certificate will not be allowed.
509
510*allow_expired_certs* Set to 1 to allow certificates that have either expired,
511or are not yet valid to be allowed, else 0.
512
513*SECTION: PKI/RPK: coap_dtls_pki_t: Certificate Chain Validation*
514
515*cert_chain_validation* Set to 1 to check that the certificate chain is valid,
516else 0.
517
518*cert_chain_verify_depth* Set to the chain depth that is to be checked. This
519is the number of intermediate CAs in the chain. If set to 0, then there can be
520no intermediate CA in the chain.
521
522*SECTION: PKI/RPK: coap_dtls_pki_t: Certificate Revocation*
523
524*check_cert_revocation* Set to 1 to check whether any certificate in the chain
525has been revoked, else 0.
526
527*allow_no_crl* Set to 1 to not check any certificate that does not have a CRL,
528else 0.
529
530*allow_expired_crl* Set to 1 to allow an certificate that has an expired CRL
531definition to be valid, else 0.
532
533*SECTION: PKI/RPK: coap_dtls_pki_t: Other*
534
535*allow_bad_md_hash* Set to 1 if unsupported MD hashes are allowed, else 0.
536
537*allow_short_rsa_length* Set to 1 if small RSA keysizes are allowed, else 0.
538
539*is_rpk_not_cert* Set to 1 if the Certificate is actually a Raw Public Key.
540If set, PKI key format type cannot be COAP_PKI_KEY_PEM.  If set,
541check_common_ca, allow_self_signed, allow_expired_certs,
542cert_chain_validation, cert_chain_verify_depth, check_cert_revocation,
543allow_no_crl, allow_expired_crl, allow_bad_md_hash and
544allow_short_rsa_length settings are all ignored.
545
546*SECTION: PKI/RPK: coap_dtls_pki_t: Reserved*
547
548*reserved* All must be set to 0.  Future functionality updates will make use of
549these reserved definitions.
550
551*SECTION: PKI/RPK: coap_dtls_pki_t: Common Name (CN) Callback*
552[source, c]
553----
554#define COAP_DTLS_RPK_CERT_CN "RPK"
555
556/**
557 * CN Validation callback that can be set up by coap_context_set_pki().
558 * Invoked when libcoap has done the validation checks at the TLS level,
559 * but the application needs to check that the CN is allowed.
560 * CN is the SubjectAltName in the cert, if not present, then the leftmost
561 * Common Name (CN) component of the subject name.
562 * NOTE: If using RPK, then the Public Key does not contain a CN, but the
563 * content of COAP_DTLS_RPK_CERT_CN is presented for the @p cn parameter.
564 *
565 * @param cn  The determined CN from the certificate
566 * @param asn1_public_cert  The ASN.1 encoded (DER) X.509 certificate
567 * @param asn1_length  The ASN.1 length
568 * @param session  The coap session associated with the certificate update
569 * @param depth  Depth in cert chain.  If 0, then client cert, else a CA
570 * @param validated  TLS can find no issues if 1
571 * @param arg  The same as was passed into coap_context_set_pki()
572 *             in setup_data->cn_call_back_arg
573 *
574 * @return 1 if accepted, else 0 if to be rejected
575 */
576typedef int (*coap_dtls_cn_callback_t)(const char *cn,
577             const uint8_t *asn1_public_cert,
578             size_t asn1_length,
579             coap_session_t *session,
580             unsigned int depth,
581             int validated,
582             void *arg);
583----
584
585*validate_cn_call_back* points to an application provided CN callback
586checking function or NULL. The application can make use of this CN information
587to decide, for example, that the CN is valid coming from a particular peer.
588The Callback returns 1 on success, 0 if the TLS connection is to be aborted.
589
590*cn_call_back_arg* points to a user defined set of data that will get passed
591in to the validate_cn_call_back() function and can be used by that function.
592An example would be a set of CNs that are allowed.
593
594*SECTION: PKI/RPK: coap_dtls_pki_t: Subject Name Identifier (SNI) Callback*
595[source, c]
596----
597typedef struct coap_dtls_key_t {
598  coap_pki_key_t key_type;          /* key format type */
599  union {
600    coap_pki_key_pem_t pem;         /* for PEM file keys */
601    coap_pki_key_pem_buf_t pem_buf; /* for PEM memory keys */
602    coap_pki_key_asn1_t asn1;       /* for ASN.1 (DER) memory keys */
603    coap_pki_key_pkcs11_t pkcs11;   /* for PKCS11 keys */
604  } key;
605} coap_dtls_key_t;
606
607/**
608 * SNI Validation callback that can be set up by coap_context_set_pki().
609 * Invoked if the SNI is not previously seen and prior to sending a certificate
610 * set back to the client so that the appropriate certificate set can be used
611 * based on the requesting SNI.
612 *
613 * @param sni  The requested SNI
614 * @param arg  The same as was passed into coap_context_set_pki()
615 *             in setup_data->sni_call_back_arg
616 *
617 * @return new set of certificates to use, or NULL if SNI is to be rejected.
618 */
619typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni,
620             void* arg);
621----
622
623*validate_sni_call_back* points to an application provided SNI callback
624checking function or NULL. The application can make use of this SNI information
625to decide whether the SNI is valid, and what set of certificates to give to the
626client.  Thus it is possible for the coap server to host multiple domains with
627different certificates allocated to each domain.
628The Callback returns a pointer to the certificates to use for this SNI, or NULL
629if the connection it to get rejected.  libcoap remembers the association
630between the SNI and Certificate set and will only invoke this callback if the
631SNI is unknown.
632
633*sni_call_back_arg* points to a user defined set of data that will get passed
634in to the validate_sni_call_back() function and can be used by that function.
635An example would be a set of SNIs that are allowed with their matching
636certificate sets.
637
638*SECTION: PKI/RPK: coap_dtls_pki_t: Application Additional Setup Callback*
639[source, c]
640----
641/**
642 * Additional Security setup handler that can be set up by
643 * coap_context_set_pki().
644 * Invoked when libcoap has done the validation checks at the TLS level,
645 * but the application needs to do some additional checks/changes/updates.
646 *
647 * @param session The security session definition - e.g. SSL * for OpenSSL.
648 *                This will be dependent on the underlying TLS library
649 *                - see coap_get_tls_library_version()
650 * @param setup_data A structure containing setup data originally passed into
651 *                   coap_context_set_pki() or coap_new_client_session_pki().
652 * @return 1 if successful, else 0
653 */
654typedef int (*coap_dtls_security_setup_t)(void *context, void* session,
655                                          coap_dtls_pki_t *setup_data);
656----
657
658*additional_tls_setup_call_back* points to an application provided callback
659function that will do additional checking/changes/updates after libcoap has
660done all of the configured TLS setup checking, or NULL to do no additional
661checking.
662
663*SECTION: PKI/RPK: coap_dtls_pki_t: Subject Name Indicator (SNI) Definition*
664
665*client_sni* points to the SNI name that will be added in as a TLS extension,
666or set NULL.  This typically is the DNS name of the server that the client is
667trying to contact.  This is only used by a client application and the server
668is then able to decide, based on the name in the SNI extension, whether, for
669example, a different certificate should be provided.
670
671*SECTION: PKI/RPK: coap_dtls_pki_t: Key Type Definition*
672[source, c]
673----
674typedef enum coap_pki_key_t {
675  COAP_PKI_KEY_PEM,     /* The PKI key type is PEM file */
676  COAP_PKI_KEY_ASN1,    /* The PKI key type is ASN.1 (DER) buffer */
677  COAP_PKI_KEY_PEM_BUF, /* The PKI key type is PEM buffer */
678  COAP_PKI_KEY_PKCS11,  /* The PKI key type is PKCS11 (DER) */
679} coap_pki_key_t;
680----
681
682*key_type* defines the format that the certificates / keys are provided in.
683This can be COAP_PKI_KEY_PEM, COAP_PKI_KEY_PEM_BUF, COAP_PKI_KEY_ASN1 or
684COAP_PKI_KEY_PKCS11.
685
686*SECTION: PKI: coap_dtls_pki_t: PEM Key Definitions*
687[source, c]
688----
689typedef struct coap_pki_key_pem_t {
690  const char *ca_file;       /* File location of Common CA in PEM format */
691  const char *public_cert;   /* File location of Public Cert */
692  const char *private_key;   /* File location of Private Key in PEM format */
693} coap_pki_key_pem_t;
694----
695
696*key.pem.ca_file* points to the CA File location on disk which will be in
697PEM format, or NULL. This file should only contain one CA (that has signed the
698public certificate) as this is passed from the server to the client when
699requesting the client's certificate. This certificate is also added into
700the valid root CAs list if not already present.
701
702*key.pem.public_cert* points to the public certificate location on disk which
703will be in PEM format.
704
705*key.pem.private_key* points to the private key location on disk which
706will be in PEM format.  This file cannot be password protected.
707
708*SECTION: PKI/RPK: coap_dtls_pki_t: PEM Memory Key Definitions*
709[source, c]
710----
711typedef struct coap_pki_key_pem_buf_t {
712  const uint8_t *ca_cert;     /* PEM buffer Common CA Cert */
713  const uint8_t *public_cert; /* PEM buffer Public Cert, or Public Key if RPK */
714  const uint8_t *private_key; /* PEM buffer Private Key */
715                                 If RPK and 'EC PRIVATE KEY' this can be used
716                                 for both the public_cert and private_key */
717  size_t ca_cert_len;         /* PEM buffer CA Cert length */
718  size_t public_cert_len;     /* PEM buffer Public Cert length */
719  size_t private_key_len;     /* PEM buffer Private Key length */
720} coap_pki_key_pem_buf_t;
721----
722
723*key.pem_buf.ca_cert* points to the CA location in memory which will be in
724PEM format, or NULL. This file should only contain one CA (that has signed the
725public certificate) as this is passed from the server to the client when
726requesting the client's certificate. This certificate is also added into
727the valid root CAs list if not already present.
728
729*key.pem_buf.ca_cert_len* is the length of the CA.
730
731*key.pem_buf.public_cert* points to the public certificate (or public key if
732RPK) location in memory which will be in PEM format.
733
734*key.pem_buf.public_cert_len* is the length of the public certificate.
735
736*key.pem_buf.private_key* points to the private key location in memory which
737will be in PEM format.  This data cannot be password protected. If RPK and
738'EC PRIVATE KEY' this can be used for both the public_cert and private_key.
739
740*key.pem_buf.private_key* is the length of the private key.
741
742*NOTE:* The PEM buffer Certs and Key should be be NULL terminated strings for
743performance reasons (to save a potential buffer copy) and the length include
744this NULL terminator. It is not a requirement to have the NULL terminator
745though and the length must then reflect the actual data size.
746
747*SECTION: PKI/RPK: coap_dtls_pki_t: ASN1 Key Definitions*
748[source, c]
749----
750typedef struct coap_pki_key_asn1_t {
751  const uint8_t *ca_cert;     /* ASN1 Common CA Certificate */
752  const uint8_t *public_cert; /* ASN1 (DER) Public Cert, or Public Key if RPK */
753  const uint8_t *private_key; /* ASN1 Private Key */
754  int ca_cert_len;            /* ASN1 CA Certificate length */
755  int public_cert_len;        /* ASN1 Public Certificate length */
756  int private_key_len;        /* ASN1 Private Key length */
757  coap_asn1_privatekey_type_t private_key_type; /* Private Key Type
758                                                   COAP_ASN1_PKEY_* */
759} coap_pki_key_asn1_t;
760
761typedef enum coap_asn1_privatekey_type_t {
762  COAP_ASN1_PKEY_NONE,
763  COAP_ASN1_PKEY_RSA,
764  COAP_ASN1_PKEY_RSA2,
765  COAP_ASN1_PKEY_DSA,
766  COAP_ASN1_PKEY_DSA1,
767  COAP_ASN1_PKEY_DSA2,
768  COAP_ASN1_PKEY_DSA3,
769  COAP_ASN1_PKEY_DSA4,
770  COAP_ASN1_PKEY_DH,
771  COAP_ASN1_PKEY_DHX,
772  COAP_ASN1_PKEY_EC,
773  COAP_ASN1_PKEY_HMAC,
774  COAP_ASN1_PKEY_CMAC,
775  COAP_ASN1_PKEY_TLS1_PRF,
776  COAP_ASN1_PKEY_HKDF
777} coap_asn1_privatekey_type_t;
778----
779
780*key.asn1.ca_cert* points to a DER encoded ASN.1 definition of the CA
781Certificate, or NULL.  This certificate is passed from the server to the client
782when requesting the client's certificate. This certificate is also added into
783the valid root CAs list if not already present.
784
785*key.asn1.public_cert* points to a DER encoded ASN.1 definition of the
786public certificate (or public key if RPK).
787
788*key.asn1.private_key* points to DER encoded ASN.1 definition of the
789private key.
790
791*key.asn1.ca_cert_len* is the length of the DER encoded ASN.1 definition of
792the CA Certificate.
793
794*key.asn1.public_cert_len* is the length of the DER encoded ASN.1 definition
795of the public certificate.
796
797*key.asn1.private_key_len* is the length of the DER encoded ASN.1 definition
798of the private key.
799
800*key.asn1.private_key_type* is the encoding type of the DER encoded ASN.1
801definition of the private key.  This will be one of the COAP_ASN1_PKEY_*
802definitions.
803
804*SECTION: PKI: coap_dtls_pki_t: PKCS11 Key Definitions*
805[source, c]
806----
807typedef struct coap_pki_key_pkcs11_t {
808  const char *ca;            /* pkcs11: URI for Common CA Certificate */
809  const char *public_cert;   /* pkcs11: URI for Public Cert */
810  const char *private_key;   /* pkcs11: URI for Private Key */
811  const char *pin;           /* pin to access PKCS11.  If NULL, then
812                                pin-value= parameter must be set in
813                                pkcs11: URI as a query. */
814} coap_pki_key_pkcs11_t;
815----
816
817*key.pkcs11.ca* is a pkcs11: URI for the CA certificate or NULL.  This is for
818the CA (that has signed the public certificate) as this is passed from the
819server to the client when requesting the client's certificate. This certificate
820is also added into the valid root CAs list if not already present.
821An example URI is 'pkcs11:pkcs11:token=My%20Token;id=%aa%bb%cc%dd' which is
822for token 'My Token' and (hex) id of 'aabbccdd'.
823
824*key.pkcs11.public_cert* is a pkcs11: URI for the Public Certificate which
825was signed by *key.pkcs11.ca* or NULL.
826
827*key.pkcs11.private_key* is a pkcs11: URI for the Private Key for the
828public certificate defined by *key.pkcs11.public_cert* or NULL.
829
830*key.pkcs11.user_pin* is the user pin used to unlock the token or NULL.
831If NULL, the pin can be defined on the other pkcs11: URI entries by using
832pin-value=XXX as a query - e.g.
833'pkcs11:pkcs11:token=My%20Token;id=%aa%bb%cc%dd?pin-value=XXX' where XXX is
834the user pin.
835
836EXAMPLES
837--------
838*CoAP Server DTLS PKI Setup*
839[source, c]
840----
841#include <coap@LIBCOAP_API_VERSION@/coap.h>
842
843typedef struct valid_cns_t {
844  int count;
845  char **cn_list;
846} valid_cns_t;
847
848/**
849 * CN Validation callback that can be set up by coap_context_set_pki().
850 * Invoked when libcoap has done the validation checks at the TLS level,
851 * but the application needs to check that the CN is allowed.
852 * CN is the SubjectAltName in the cert, if not present, then the leftmost
853 * Common Name (CN) component of the subject name.
854 * NOTE: If using RPK, then the Public Key does not contain a CN, but "RPK"
855 * is presented for the cn parameter.
856 *
857 * @param cn  The determined CN from the certificate
858 * @param asn1_public_cert  The ASN.1 encoded (DER) X.509 certificate
859 * @param asn1_length  The ASN.1 length
860 * @param session  The coap session associated with the certificate update
861 * @param depth  Depth in cert chain.  If 0, then client cert, else a CA
862 * @param validated  TLS can find no issues if 1
863 * @param arg  The same as was passed into coap_context_set_pki()
864 *             in setup_data->cn_call_back_arg
865 *
866 * @return 1 if accepted, else 0 if to be rejected
867 */
868static int
869verify_cn_callback(const char *cn,
870                   const uint8_t *asn1_public_cert,
871                   size_t asn1_length,
872                   coap_session_t *c_session,
873                   unsigned depth,
874                   int validated,
875                   void *arg
876) {
877  valid_cns_t *valid_cn_list = (valid_cns_t*)arg;
878  int i;
879  /* Remove (void) definition if variable is used */
880  (void)asn1_public_cert;
881  (void)asn1_length;
882  (void)c_session;
883  (void)depth;
884  (void)validated;
885
886  /* Check that the CN is valid */
887  for (i = 0; i < valid_cn_list->count; i++) {
888    if (!strcasecmp(cn, valid_cn_list->cn_list[i])) {
889      return 1;
890    }
891  }
892  return 0;
893}
894
895typedef struct sni_def_t {
896  char* sni;
897  coap_dtls_key_t key;
898} sni_def_t;
899
900typedef struct valid_snis_t {
901  int count;
902  sni_def_t *sni_list;
903} valid_snis_t;
904
905/**
906 * SNI Validation callback that is set up by coap_context_set_pki().
907 * Invoked if the SNI is not previously seen and prior to sending a certificate
908 * set back to the client so that the appropriate certificate set can be used
909 * based on the requesting SNI.
910 *
911 * @param sni  The requested SNI
912 * @param arg  The same as was passed into coap_context_set_pki()
913 *             in setup_data->sni_call_back_arg
914 *
915 * @return new set of certificates to use, or NULL if SNI is to be rejected.
916 */
917static coap_dtls_key_t *
918verify_pki_sni_callback(const char *sni,
919                        void *arg
920) {
921  valid_snis_t *valid_sni_list = (valid_snis_t *)arg;
922  int i;
923
924  /* Check that the SNI is valid */
925  for (i = 0; i < valid_sni_list->count; i++) {
926    if (!strcasecmp(sni, valid_sni_list->sni_list[i].sni)) {
927      return &valid_sni_list->sni_list[i].key;
928    }
929  }
930  return NULL;
931}
932
933/*
934 * Set up PKI encryption information
935 */
936static coap_context_t *
937setup_server_context_pki (const char *public_cert_file,
938                          const char *private_key_file,
939                          const char *ca_file,
940                          valid_cns_t *valid_cn_list,
941                          valid_snis_t *valid_sni_list
942) {
943  coap_endpoint_t *endpoint;
944  coap_address_t listen_addr;
945  coap_dtls_pki_t dtls_pki;
946  coap_context_t *context;
947
948  /* See coap_tls_library(3) */
949  if (!coap_dtls_is_supported())
950    return NULL;
951
952  /* See coap_context(3) */
953  context = coap_new_context(NULL);
954  if (!context)
955    return NULL;
956  /* See coap_block(3) */
957  coap_context_set_block_mode(context,
958                              COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
959
960
961  memset (&dtls_pki, 0, sizeof (dtls_pki));
962
963  dtls_pki.version                 = COAP_DTLS_PKI_SETUP_VERSION;
964  dtls_pki.verify_peer_cert        = 1;
965  dtls_pki.check_common_ca         = 1;
966  dtls_pki.allow_self_signed       = 1;
967  dtls_pki.allow_expired_certs     = 1;
968  dtls_pki.cert_chain_validation   = 1;
969  dtls_pki.cert_chain_verify_depth = 1;
970  dtls_pki.check_cert_revocation   = 1;
971  dtls_pki.allow_no_crl            = 1;
972  dtls_pki.allow_expired_crl       = 1;
973  dtls_pki.allow_bad_md_hash       = 0;
974  dtls_pki.allow_short_rsa_length  = 0;
975  dtls_pki.is_rpk_not_cert         = 0; /* Set to 1 if RPK */
976  dtls_pki.validate_cn_call_back   = verify_cn_callback;
977  dtls_pki.cn_call_back_arg        = valid_cn_list;
978  dtls_pki.validate_sni_call_back  = verify_pki_sni_callback;
979  dtls_pki.sni_call_back_arg       = valid_sni_list;
980  dtls_pki.additional_tls_setup_call_back = NULL;
981  dtls_pki.client_sni              = NULL;
982  dtls_pki.pki_key.key_type        = COAP_PKI_KEY_PEM;
983  dtls_pki.pki_key.key.pem.ca_file = ca_file;
984  dtls_pki.pki_key.key.pem.public_cert = public_cert_file;
985  dtls_pki.pki_key.key.pem.private_key = private_key_file;
986
987  /* See coap_context(3) */
988  if (coap_context_set_pki(context, &dtls_pki)) {
989    coap_free_context(context);
990    return NULL;
991  }
992
993  coap_address_init(&listen_addr);
994  listen_addr.addr.sa.sa_family = AF_INET;
995  listen_addr.addr.sin.sin_port = htons (5684);
996
997  /* See coap_context(3) */
998  endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS);
999  if (!endpoint) {
1000    coap_free_context(context);
1001    return NULL;
1002  }
1003
1004  /* Initialize resources - See coap_resource(3) init_resources() example */
1005
1006  return context;
1007}
1008----
1009
1010*CoAP Server DTLS PSK Setup*
1011[source, c]
1012----
1013#include <coap@LIBCOAP_API_VERSION@/coap.h>
1014
1015typedef struct id_def_t {
1016  char *hint_match;
1017  coap_bin_const_t id;
1018  coap_bin_const_t key;
1019} id_def_t;
1020
1021typedef struct valid_ids_t {
1022  size_t count;
1023  id_def_t *id_list;
1024} valid_ids_t;
1025
1026/*
1027 * PSK Identity Pre-Shared Key selection Callback function
1028 */
1029static const coap_bin_const_t *
1030verify_id_callback(coap_bin_const_t *identity,
1031                   coap_session_t *c_session,
1032                   void *arg
1033) {
1034  valid_ids_t *valid_id_list = (valid_ids_t*)arg;
1035  const coap_bin_const_t *s_psk_hint = coap_session_get_psk_hint(c_session);
1036  size_t i;
1037
1038  /* Check that the Identity is valid */
1039  for (i = 0; i < valid_id_list->count; i++) {
1040    if (s_psk_hint &&
1041        strcmp((const char *)s_psk_hint->s,
1042               valid_id_list->id_list[i].hint_match)) {
1043      continue;
1044    }
1045    if (coap_binary_equal(identity, &valid_id_list->id_list[i].id)) {
1046      return &valid_id_list->id_list[i].key;
1047    }
1048  }
1049  return NULL;
1050}
1051
1052typedef struct sni_psk_def_t {
1053  char* sni;
1054  coap_dtls_spsk_info_t psk_info;
1055} sni_psk_def_t;
1056
1057typedef struct valid_psk_snis_t {
1058  int count;
1059  sni_psk_def_t *sni_list;
1060} valid_psk_snis_t;
1061
1062/*
1063 * PSK Subject Name Identifier (SNI) callback verifier
1064 */
1065static const coap_dtls_spsk_info_t *
1066verify_psk_sni_callback(const char *sni,
1067                        coap_session_t *c_session,
1068                        void *arg
1069) {
1070  valid_psk_snis_t *valid_sni_list = (valid_psk_snis_t *)arg;
1071  int i;
1072  /* Remove (void) definition if variable is used */
1073  (void)c_session;
1074
1075  /* Check that the SNI is valid */
1076  for (i = 0; i < valid_sni_list->count; i++) {
1077    if (!strcasecmp(sni, valid_sni_list->sni_list[i].sni)) {
1078      return &valid_sni_list->sni_list[i].psk_info;
1079    }
1080  }
1081  return NULL;
1082}
1083
1084static coap_context_t *
1085setup_server_context_psk (const char *hint,
1086                          const uint8_t *key,
1087                          unsigned int key_len,
1088                          valid_ids_t *valid_id_list,
1089                          valid_psk_snis_t *valid_sni_list
1090) {
1091  coap_endpoint_t *endpoint;
1092  coap_address_t listen_addr;
1093  coap_context_t *context;
1094  coap_dtls_spsk_t dtls_psk;
1095
1096  /* See coap_tls_library(3) */
1097  if (!coap_dtls_is_supported())
1098    return NULL;
1099
1100  context = coap_new_context(NULL);
1101  if (!context)
1102    return NULL;
1103  /* See coap_block(3) */
1104  coap_context_set_block_mode(context,
1105                              COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
1106
1107
1108  memset (&dtls_psk, 0, sizeof (dtls_psk));
1109
1110  /* see coap_encryption(3) */
1111  dtls_psk.version                 = COAP_DTLS_SPSK_SETUP_VERSION;
1112  dtls_psk.validate_id_call_back   = verify_id_callback;
1113  dtls_psk.id_call_back_arg        = valid_id_list;
1114  dtls_psk.validate_sni_call_back  = verify_psk_sni_callback;
1115  dtls_psk.sni_call_back_arg       = valid_sni_list;
1116  dtls_psk.psk_info.hint.s         = (const uint8_t*)hint;
1117  dtls_psk.psk_info.hint.length    = hint ? strlen(hint) : 0;
1118  dtls_psk.psk_info.key.s          = key;
1119  dtls_psk.psk_info.key.length     = key_len;
1120
1121  if (coap_context_set_psk2(context, &dtls_psk)) {
1122    coap_free_context(context);
1123    return NULL;
1124  }
1125
1126  coap_address_init(&listen_addr);
1127  listen_addr.addr.sa.sa_family = AF_INET;
1128  listen_addr.addr.sin.sin_port = htons (5684);
1129
1130  endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS);
1131  if (!endpoint) {
1132    coap_free_context(context);
1133    return NULL;
1134  }
1135
1136  /* Initialize resources - See coap_resource(3) init_resources() example */
1137
1138  return context;
1139}
1140----
1141
1142*CoAP Client DTLS PSK Setup*
1143[source, c]
1144----
1145#include <coap@LIBCOAP_API_VERSION@/coap.h>
1146
1147#include <stdio.h>
1148
1149#ifndef min
1150#define min(a,b) ((a) < (b) ? (a) : (b))
1151#endif
1152
1153static const coap_dtls_cpsk_info_t *
1154verify_ih_callback(coap_str_const_t *hint,
1155                   coap_session_t *c_session,
1156                   void *arg
1157) {
1158  coap_dtls_cpsk_info_t *psk_info = (coap_dtls_cpsk_info_t *)arg;
1159  /* Remove (void) definition if variable is used */
1160  (void)c_session;
1161
1162  coap_log_info("Identity Hint '%.*s' provided\n", (int)hint->length, hint->s);
1163
1164  /* Just use the defined information for now as passed in by arg */
1165  return psk_info;
1166}
1167
1168static coap_dtls_cpsk_t dtls_psk;
1169static char client_sni[256];
1170
1171static coap_session_t *
1172setup_client_session_psk (const char *uri,
1173                          struct in_addr ip_address,
1174                          const uint8_t *identity,
1175                          unsigned int identity_len,
1176                          const uint8_t *key,
1177                          unsigned int key_len
1178) {
1179  coap_session_t *session;
1180  coap_address_t server;
1181  /* See coap_context(3) */
1182  coap_context_t *context = coap_new_context(NULL);
1183
1184  if (!context)
1185    return NULL;
1186  /* See coap_block(3) */
1187  coap_context_set_block_mode(context,
1188                              COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
1189
1190
1191  coap_address_init(&server);
1192  server.addr.sa.sa_family = AF_INET;
1193  server.addr.sin.sin_addr = ip_address;
1194  server.addr.sin.sin_port = htons (5684);
1195
1196  /* See coap_encryption(3) */
1197  memset (&dtls_psk, 0, sizeof(dtls_psk));
1198  dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION;
1199  dtls_psk.validate_ih_call_back = verify_ih_callback;
1200  dtls_psk.ih_call_back_arg = &dtls_psk.psk_info;
1201  if (uri)
1202    memcpy(client_sni, uri, min(strlen(uri), sizeof(client_sni)-1));
1203  else
1204    memcpy(client_sni, "localhost", 9);
1205  dtls_psk.client_sni = client_sni;
1206  dtls_psk.psk_info.identity.s = identity;
1207  dtls_psk.psk_info.identity.length = identity_len;
1208  dtls_psk.psk_info.key.s = key;
1209  dtls_psk.psk_info.key.length = key_len;
1210  session = coap_new_client_session_psk2(context, NULL, &server,
1211                                        COAP_PROTO_DTLS, &dtls_psk);
1212  if (!session) {
1213    coap_free_context(context);
1214    return NULL;
1215  }
1216  /* The context is in session->context */
1217  return session;
1218}
1219----
1220
1221SEE ALSO
1222--------
1223*coap_block*(3), *coap_context*(3), *coap_resource*(3), *coap_session*(3) and
1224*coap_tls_library*(3)
1225
1226FURTHER INFORMATION
1227-------------------
1228See
1229
1230"https://rfc-editor.org/rfc/rfc7252[RFC7252: The Constrained Application Protocol (CoAP)]"
1231
1232for further information.
1233
1234BUGS
1235----
1236Please report bugs on the mailing list for libcoap:
1237libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
1238https://github.com/obgm/libcoap/issues
1239
1240AUTHORS
1241-------
1242The libcoap project <libcoap-developers@lists.sourceforge.net>
1243