open62541 1.3.12
Open source implementation of OPC UA
Loading...
Searching...
No Matches
mbedtls_sockets.h
Go to the documentation of this file.
1#if !defined(__MBEDTLS_SOCKET_TEMPLATE_H__)
2#define __MBEDTLS_SOCKET_TEMPLATE_H__
3
4#include <inttypes.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8
9#include <mbedtls/error.h>
10#include <mbedtls/entropy.h>
11#include <mbedtls/ctr_drbg.h>
12#include <mbedtls/net_sockets.h>
13#include <mbedtls/ssl.h>
14
15#if !defined(MBEDTLS_NET_POLL_READ)
16/** compat for older mbedtls */
17#define MBEDTLS_NET_POLL_READ 1
18#define MBEDTLS_NET_POLL_WRITE 1
19
20int
21mbedtls_net_poll(mbedtls_net_context * ctx, uint32_t rw, uint32_t timeout)
22{
23 /* XXX this is not ideal but good enough for an example */
24 usleep(300);
25 return 1;
26}
27#endif
28
30 mbedtls_net_context net_ctx;
31 mbedtls_ssl_context ssl_ctx;
32 mbedtls_ssl_config ssl_conf;
33 mbedtls_x509_crt ca_crt;
34 mbedtls_entropy_context entropy;
35 mbedtls_ctr_drbg_context ctr_drbg;
36};
37
38void failed(const char *fn, int rv);
39void cert_verify_failed(uint32_t rv);
40void open_nb_socket(struct mbedtls_context *ctx,
41 const char *hostname,
42 const char *port,
43 const char *ca_file);
44
45
46void failed(const char *fn, int rv) {
47 char buf[100];
48 mbedtls_strerror(rv, buf, sizeof(buf));
49 printf("%s failed with %x (%s)\n", fn, -rv, buf);
50 exit(1);
51}
52
53void cert_verify_failed(uint32_t rv) {
54 char buf[512];
55 mbedtls_x509_crt_verify_info(buf, sizeof(buf), "\t", rv);
56 printf("Certificate verification failed (%0" PRIx32 ")\n%s\n", rv, buf);
57 exit(1);
58}
59
60/*
61 A template for opening a non-blocking mbed TLS connection.
62*/
64 const char *hostname,
65 const char *port,
66 const char *ca_file) {
67 const unsigned char *additional = (const unsigned char *)"MQTT-C";
68 size_t additional_len = 6;
69 int rv;
70
71 mbedtls_net_context *net_ctx = &ctx->net_ctx;
72 mbedtls_ssl_context *ssl_ctx = &ctx->ssl_ctx;
73 mbedtls_ssl_config *ssl_conf = &ctx->ssl_conf;
74 mbedtls_x509_crt *ca_crt = &ctx->ca_crt;
75 mbedtls_entropy_context *entropy = &ctx->entropy;
76 mbedtls_ctr_drbg_context *ctr_drbg = &ctx->ctr_drbg;
77
78 mbedtls_entropy_init(entropy);
79 mbedtls_ctr_drbg_init(ctr_drbg);
80 rv = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, entropy,
81 additional, additional_len);
82 if (rv != 0) {
83 failed("mbedtls_ctr_drbg_seed", rv);
84 }
85
86 mbedtls_x509_crt_init(ca_crt);
87 rv = mbedtls_x509_crt_parse_file(ca_crt, ca_file);
88 if (rv != 0) {
89 failed("mbedtls_x509_crt_parse_file", rv);
90 }
91
92 mbedtls_ssl_config_init(ssl_conf);
93 rv = mbedtls_ssl_config_defaults(ssl_conf, MBEDTLS_SSL_IS_CLIENT,
94 MBEDTLS_SSL_TRANSPORT_STREAM,
95 MBEDTLS_SSL_PRESET_DEFAULT);
96 if (rv != 0) {
97 failed("mbedtls_ssl_config_defaults", rv);
98 }
99 mbedtls_ssl_conf_ca_chain(ssl_conf, ca_crt, NULL);
100 mbedtls_ssl_conf_authmode(ssl_conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
101 mbedtls_ssl_conf_rng(ssl_conf, mbedtls_ctr_drbg_random, ctr_drbg);
102
103 mbedtls_net_init(net_ctx);
104 rv = mbedtls_net_connect(net_ctx, hostname, port, MBEDTLS_NET_PROTO_TCP);
105 if (rv != 0) {
106 failed("mbedtls_net_connect", rv);
107 }
108 rv = mbedtls_net_set_nonblock(net_ctx);
109 if (rv != 0) {
110 failed("mbedtls_net_set_nonblock", rv);
111 }
112
113 mbedtls_ssl_init(ssl_ctx);
114 rv = mbedtls_ssl_setup(ssl_ctx, ssl_conf);
115 if (rv != 0) {
116 failed("mbedtls_ssl_setup", rv);
117 }
118 rv = mbedtls_ssl_set_hostname(ssl_ctx, hostname);
119 if (rv != 0) {
120 failed("mbedtls_ssl_set_hostname", rv);
121 }
122 mbedtls_ssl_set_bio(ssl_ctx, net_ctx,
123 mbedtls_net_send, mbedtls_net_recv, NULL);
124
125 for (;;) {
126 rv = mbedtls_ssl_handshake(ssl_ctx);
127 uint32_t want = 0;
128 if (rv == MBEDTLS_ERR_SSL_WANT_READ) {
129 want |= MBEDTLS_NET_POLL_READ;
130 } else if (rv == MBEDTLS_ERR_SSL_WANT_WRITE) {
132 } else {
133 break;
134 }
135 rv = mbedtls_net_poll(net_ctx, want, (uint32_t)-1);
136 if (rv < 0) {
137 failed("mbedtls_net_poll", rv);
138 }
139 }
140 if (rv != 0) {
141 failed("mbedtls_ssl_handshake", rv);
142 }
143 uint32_t result = mbedtls_ssl_get_verify_result(ssl_ctx);
144 if (result != 0) {
145 if (result == (uint32_t)-1) {
146 failed("mbedtls_ssl_get_verify_result", (int)result);
147 } else {
148 cert_verify_failed(result);
149 }
150 }
151}
152
153#endif
void open_nb_socket(struct mbedtls_context *ctx, const char *hostname, const char *port, const char *ca_file)
#define MBEDTLS_NET_POLL_READ
compat for older mbedtls
#define MBEDTLS_NET_POLL_WRITE
int mbedtls_net_poll(mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout)
void cert_verify_failed(uint32_t rv)
void failed(const char *fn, int rv)
mbedtls_ssl_context ssl_ctx
mbedtls_x509_crt ca_crt
mbedtls_entropy_context entropy
mbedtls_ctr_drbg_context ctr_drbg
mbedtls_net_context net_ctx
mbedtls_ssl_config ssl_conf