The patch looks huge, but it's just file renames, and required changes in
includes / Makefiles. Use 'git diff -C' or a tool like gitk to easily
review this patch.
Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1460918143-408-2-git-send-email-steffan@karger.me>
URL: http://article.gmane.org/gmane.network.openvpn.devel/11459
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -46,7 +46,7 @@ openvpn_SOURCES = \ |
46 | 46 |
comp-lz4.c comp-lz4.h \ |
47 | 47 |
crypto.c crypto.h crypto_backend.h \ |
48 | 48 |
crypto_openssl.c crypto_openssl.h \ |
49 |
- crypto_polarssl.c crypto_polarssl.h \ |
|
49 |
+ crypto_mbedtls.c crypto_mbedtls.h \ |
|
50 | 50 |
dhcp.c dhcp.h \ |
51 | 51 |
errlevel.h \ |
52 | 52 |
error.c error.h \ |
... | ... |
@@ -80,7 +80,7 @@ openvpn_SOURCES = \ |
80 | 80 |
occ.c occ.h occ-inline.h \ |
81 | 81 |
pkcs11.c pkcs11.h pkcs11_backend.h \ |
82 | 82 |
pkcs11_openssl.c \ |
83 |
- pkcs11_polarssl.c \ |
|
83 |
+ pkcs11_mbedtls.c \ |
|
84 | 84 |
openvpn.c openvpn.h \ |
85 | 85 |
options.c options.h \ |
86 | 86 |
otime.c otime.h \ |
... | ... |
@@ -105,11 +105,11 @@ openvpn_SOURCES = \ |
105 | 105 |
socks.c socks.h \ |
106 | 106 |
ssl.c ssl.h ssl_backend.h \ |
107 | 107 |
ssl_openssl.c ssl_openssl.h \ |
108 |
- ssl_polarssl.c ssl_polarssl.h \ |
|
108 |
+ ssl_mbedtls.c ssl_mbedtls.h \ |
|
109 | 109 |
ssl_common.h \ |
110 | 110 |
ssl_verify.c ssl_verify.h ssl_verify_backend.h \ |
111 | 111 |
ssl_verify_openssl.c ssl_verify_openssl.h \ |
112 |
- ssl_verify_polarssl.c ssl_verify_polarssl.h \ |
|
112 |
+ ssl_verify_mbedtls.c ssl_verify_mbedtls.h \ |
|
113 | 113 |
status.c status.h \ |
114 | 114 |
syshead.h \ |
115 | 115 |
tun.c tun.h \ |
41 | 41 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,758 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
9 |
+ * |
|
10 |
+ * This program is free software; you can redistribute it and/or modify |
|
11 |
+ * it under the terms of the GNU General Public License version 2 |
|
12 |
+ * as published by the Free Software Foundation. |
|
13 |
+ * |
|
14 |
+ * This program is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 |
+ * GNU General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU General Public License |
|
20 |
+ * along with this program (see the file COPYING included with this |
|
21 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
22 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
23 |
+ */ |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @file Data Channel Cryptography mbed TLS-specific backend interface |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+#ifdef HAVE_CONFIG_H |
|
30 |
+#include "config.h" |
|
31 |
+#elif defined(_MSC_VER) |
|
32 |
+#include "config-msvc.h" |
|
33 |
+#endif |
|
34 |
+ |
|
35 |
+#include "syshead.h" |
|
36 |
+ |
|
37 |
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
38 |
+ |
|
39 |
+#include "errlevel.h" |
|
40 |
+#include "basic.h" |
|
41 |
+#include "buffer.h" |
|
42 |
+#include "integer.h" |
|
43 |
+#include "crypto_backend.h" |
|
44 |
+#include "otime.h" |
|
45 |
+#include "misc.h" |
|
46 |
+ |
|
47 |
+#include <mbedtls/des.h> |
|
48 |
+#include <mbedtls/error.h> |
|
49 |
+#include <mbedtls/md5.h> |
|
50 |
+#include <mbedtls/cipher.h> |
|
51 |
+#include <mbedtls/havege.h> |
|
52 |
+ |
|
53 |
+#include <mbedtls/entropy.h> |
|
54 |
+ |
|
55 |
+ |
|
56 |
+/* |
|
57 |
+ * |
|
58 |
+ * Hardware engine support. Allows loading/unloading of engines. |
|
59 |
+ * |
|
60 |
+ */ |
|
61 |
+ |
|
62 |
+void |
|
63 |
+crypto_init_lib_engine (const char *engine_name) |
|
64 |
+{ |
|
65 |
+ msg (M_WARN, "Note: mbed TLS hardware crypto engine functionality is not " |
|
66 |
+ "available"); |
|
67 |
+} |
|
68 |
+ |
|
69 |
+/* |
|
70 |
+ * |
|
71 |
+ * Functions related to the core crypto library |
|
72 |
+ * |
|
73 |
+ */ |
|
74 |
+ |
|
75 |
+void |
|
76 |
+crypto_init_lib (void) |
|
77 |
+{ |
|
78 |
+} |
|
79 |
+ |
|
80 |
+void |
|
81 |
+crypto_uninit_lib (void) |
|
82 |
+{ |
|
83 |
+} |
|
84 |
+ |
|
85 |
+void |
|
86 |
+crypto_clear_error (void) |
|
87 |
+{ |
|
88 |
+} |
|
89 |
+ |
|
90 |
+bool mbed_log_err(unsigned int flags, int errval, const char *prefix) |
|
91 |
+{ |
|
92 |
+ if (0 != errval) |
|
93 |
+ { |
|
94 |
+ char errstr[256]; |
|
95 |
+ mbedtls_strerror(errval, errstr, sizeof(errstr)); |
|
96 |
+ |
|
97 |
+ if (NULL == prefix) prefix = "mbed TLS error"; |
|
98 |
+ msg (flags, "%s: %s", prefix, errstr); |
|
99 |
+ } |
|
100 |
+ |
|
101 |
+ return 0 == errval; |
|
102 |
+} |
|
103 |
+ |
|
104 |
+bool mbed_log_func_line(unsigned int flags, int errval, const char *func, |
|
105 |
+ int line) |
|
106 |
+{ |
|
107 |
+ char prefix[256]; |
|
108 |
+ |
|
109 |
+ if (!openvpn_snprintf(prefix, sizeof(prefix), "%s:%d", func, line)) |
|
110 |
+ return mbed_log_err(flags, errval, func); |
|
111 |
+ |
|
112 |
+ return mbed_log_err(flags, errval, prefix); |
|
113 |
+} |
|
114 |
+ |
|
115 |
+ |
|
116 |
+#ifdef DMALLOC |
|
117 |
+void |
|
118 |
+crypto_init_dmalloc (void) |
|
119 |
+{ |
|
120 |
+ msg (M_ERR, "Error: dmalloc support is not available for mbed TLS."); |
|
121 |
+} |
|
122 |
+#endif /* DMALLOC */ |
|
123 |
+ |
|
124 |
+const cipher_name_pair cipher_name_translation_table[] = { |
|
125 |
+ { "BF-CBC", "BLOWFISH-CBC" }, |
|
126 |
+ { "BF-CFB", "BLOWFISH-CFB64" }, |
|
127 |
+ { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" }, |
|
128 |
+ { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" }, |
|
129 |
+ { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" } |
|
130 |
+}; |
|
131 |
+const size_t cipher_name_translation_table_count = |
|
132 |
+ sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table); |
|
133 |
+ |
|
134 |
+void |
|
135 |
+show_available_ciphers () |
|
136 |
+{ |
|
137 |
+ const int *ciphers = mbedtls_cipher_list(); |
|
138 |
+ |
|
139 |
+#ifndef ENABLE_SMALL |
|
140 |
+ printf ("The following ciphers and cipher modes are available for use\n" |
|
141 |
+ "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n" |
|
142 |
+ "parameter to the --cipher option. Using a CBC or GCM mode is\n" |
|
143 |
+ "recommended. In static key mode only CBC mode is allowed.\n\n"); |
|
144 |
+#endif |
|
145 |
+ |
|
146 |
+ while (*ciphers != 0) |
|
147 |
+ { |
|
148 |
+ const cipher_kt_t *info = mbedtls_cipher_info_from_type(*ciphers); |
|
149 |
+ |
|
150 |
+ if (info && (cipher_kt_mode_cbc(info) |
|
151 |
+#ifdef HAVE_AEAD_CIPHER_MODES |
|
152 |
+ || cipher_kt_mode_aead(info) |
|
153 |
+#endif |
|
154 |
+ )) |
|
155 |
+ { |
|
156 |
+ const char *ssl_only = cipher_kt_mode_cbc(info) ? |
|
157 |
+ "" : " (TLS client/server mode)"; |
|
158 |
+ |
|
159 |
+ printf ("%s %d bit default key%s\n", |
|
160 |
+ cipher_kt_name(info), cipher_kt_key_size(info) * 8, ssl_only); |
|
161 |
+ } |
|
162 |
+ |
|
163 |
+ ciphers++; |
|
164 |
+ } |
|
165 |
+ printf ("\n"); |
|
166 |
+} |
|
167 |
+ |
|
168 |
+void |
|
169 |
+show_available_digests () |
|
170 |
+{ |
|
171 |
+ const int *digests = mbedtls_md_list(); |
|
172 |
+ |
|
173 |
+#ifndef ENABLE_SMALL |
|
174 |
+ printf ("The following message digests are available for use with\n" |
|
175 |
+ PACKAGE_NAME ". A message digest is used in conjunction with\n" |
|
176 |
+ "the HMAC function, to authenticate received packets.\n" |
|
177 |
+ "You can specify a message digest as parameter to\n" |
|
178 |
+ "the --auth option.\n\n"); |
|
179 |
+#endif |
|
180 |
+ |
|
181 |
+ while (*digests != 0) |
|
182 |
+ { |
|
183 |
+ const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests); |
|
184 |
+ |
|
185 |
+ if (info) |
|
186 |
+ printf ("%s %d bit default key\n", mbedtls_md_get_name(info), |
|
187 |
+ mbedtls_md_get_size(info) * 8); |
|
188 |
+ digests++; |
|
189 |
+ } |
|
190 |
+ printf ("\n"); |
|
191 |
+} |
|
192 |
+ |
|
193 |
+void |
|
194 |
+show_available_engines () |
|
195 |
+{ |
|
196 |
+ printf ("Sorry, mbed TLS hardware crypto engine functionality is not " |
|
197 |
+ "available\n"); |
|
198 |
+} |
|
199 |
+ |
|
200 |
+/* |
|
201 |
+ * |
|
202 |
+ * Random number functions, used in cases where we want |
|
203 |
+ * reasonably strong cryptographic random number generation |
|
204 |
+ * without depleting our entropy pool. Used for random |
|
205 |
+ * IV values and a number of other miscellaneous tasks. |
|
206 |
+ * |
|
207 |
+ */ |
|
208 |
+ |
|
209 |
+/* |
|
210 |
+ * Initialise the given ctr_drbg context, using a personalisation string and an |
|
211 |
+ * entropy gathering function. |
|
212 |
+ */ |
|
213 |
+mbedtls_ctr_drbg_context * rand_ctx_get() |
|
214 |
+{ |
|
215 |
+ static mbedtls_entropy_context ec = {0}; |
|
216 |
+ static mbedtls_ctr_drbg_context cd_ctx = {0}; |
|
217 |
+ static bool rand_initialised = false; |
|
218 |
+ |
|
219 |
+ if (!rand_initialised) |
|
220 |
+ { |
|
221 |
+ struct gc_arena gc = gc_new(); |
|
222 |
+ struct buffer pers_string = alloc_buf_gc(100, &gc); |
|
223 |
+ |
|
224 |
+ /* |
|
225 |
+ * Personalisation string, should be as unique as possible (see NIST |
|
226 |
+ * 800-90 section 8.7.1). We have very little information at this stage. |
|
227 |
+ * Include Program Name, memory address of the context and PID. |
|
228 |
+ */ |
|
229 |
+ buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc)); |
|
230 |
+ |
|
231 |
+ /* Initialise mbed TLS RNG, and built-in entropy sources */ |
|
232 |
+ mbedtls_entropy_init(&ec); |
|
233 |
+ |
|
234 |
+ mbedtls_ctr_drbg_init(&cd_ctx); |
|
235 |
+ if (!mbed_ok(mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec, |
|
236 |
+ BPTR(&pers_string), BLEN(&pers_string)))) |
|
237 |
+ msg (M_FATAL, "Failed to initialize random generator"); |
|
238 |
+ |
|
239 |
+ gc_free(&gc); |
|
240 |
+ rand_initialised = true; |
|
241 |
+ } |
|
242 |
+ |
|
243 |
+ return &cd_ctx; |
|
244 |
+} |
|
245 |
+ |
|
246 |
+#ifdef ENABLE_PREDICTION_RESISTANCE |
|
247 |
+void rand_ctx_enable_prediction_resistance() |
|
248 |
+{ |
|
249 |
+ mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get(); |
|
250 |
+ |
|
251 |
+ mbedtls_ctr_drbg_set_prediction_resistance(cd_ctx, 1); |
|
252 |
+} |
|
253 |
+#endif /* ENABLE_PREDICTION_RESISTANCE */ |
|
254 |
+ |
|
255 |
+int |
|
256 |
+rand_bytes (uint8_t *output, int len) |
|
257 |
+{ |
|
258 |
+ mbedtls_ctr_drbg_context *rng_ctx = rand_ctx_get(); |
|
259 |
+ |
|
260 |
+ while (len > 0) |
|
261 |
+ { |
|
262 |
+ const size_t blen = min_int (len, MBEDTLS_CTR_DRBG_MAX_REQUEST); |
|
263 |
+ if (0 != mbedtls_ctr_drbg_random(rng_ctx, output, blen)) |
|
264 |
+ return 0; |
|
265 |
+ |
|
266 |
+ output += blen; |
|
267 |
+ len -= blen; |
|
268 |
+ } |
|
269 |
+ |
|
270 |
+ return 1; |
|
271 |
+} |
|
272 |
+ |
|
273 |
+/* |
|
274 |
+ * |
|
275 |
+ * Key functions, allow manipulation of keys. |
|
276 |
+ * |
|
277 |
+ */ |
|
278 |
+ |
|
279 |
+ |
|
280 |
+int |
|
281 |
+key_des_num_cblocks (const mbedtls_cipher_info_t *kt) |
|
282 |
+{ |
|
283 |
+ int ret = 0; |
|
284 |
+ if (kt->type == MBEDTLS_CIPHER_DES_CBC) |
|
285 |
+ ret = 1; |
|
286 |
+ if (kt->type == MBEDTLS_CIPHER_DES_EDE_CBC) |
|
287 |
+ ret = 2; |
|
288 |
+ if (kt->type == MBEDTLS_CIPHER_DES_EDE3_CBC) |
|
289 |
+ ret = 3; |
|
290 |
+ |
|
291 |
+ dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret); |
|
292 |
+ return ret; |
|
293 |
+} |
|
294 |
+ |
|
295 |
+bool |
|
296 |
+key_des_check (uint8_t *key, int key_len, int ndc) |
|
297 |
+{ |
|
298 |
+ int i; |
|
299 |
+ struct buffer b; |
|
300 |
+ |
|
301 |
+ buf_set_read (&b, key, key_len); |
|
302 |
+ |
|
303 |
+ for (i = 0; i < ndc; ++i) |
|
304 |
+ { |
|
305 |
+ unsigned char *key = buf_read_alloc(&b, MBEDTLS_DES_KEY_SIZE); |
|
306 |
+ if (!key) |
|
307 |
+ { |
|
308 |
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material"); |
|
309 |
+ goto err; |
|
310 |
+ } |
|
311 |
+ if (0 != mbedtls_des_key_check_weak(key)) |
|
312 |
+ { |
|
313 |
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected"); |
|
314 |
+ goto err; |
|
315 |
+ } |
|
316 |
+ if (0 != mbedtls_des_key_check_key_parity(key)) |
|
317 |
+ { |
|
318 |
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected"); |
|
319 |
+ goto err; |
|
320 |
+ } |
|
321 |
+ } |
|
322 |
+ return true; |
|
323 |
+ |
|
324 |
+ err: |
|
325 |
+ return false; |
|
326 |
+} |
|
327 |
+ |
|
328 |
+void |
|
329 |
+key_des_fixup (uint8_t *key, int key_len, int ndc) |
|
330 |
+{ |
|
331 |
+ int i; |
|
332 |
+ struct buffer b; |
|
333 |
+ |
|
334 |
+ buf_set_read (&b, key, key_len); |
|
335 |
+ for (i = 0; i < ndc; ++i) |
|
336 |
+ { |
|
337 |
+ unsigned char *key = buf_read_alloc(&b, MBEDTLS_DES_KEY_SIZE); |
|
338 |
+ if (!key) |
|
339 |
+ { |
|
340 |
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material"); |
|
341 |
+ return; |
|
342 |
+ } |
|
343 |
+ mbedtls_des_key_set_parity(key); |
|
344 |
+ } |
|
345 |
+} |
|
346 |
+ |
|
347 |
+/* |
|
348 |
+ * |
|
349 |
+ * Generic cipher key type functions |
|
350 |
+ * |
|
351 |
+ */ |
|
352 |
+ |
|
353 |
+ |
|
354 |
+const mbedtls_cipher_info_t * |
|
355 |
+cipher_kt_get (const char *ciphername) |
|
356 |
+{ |
|
357 |
+ const mbedtls_cipher_info_t *cipher = NULL; |
|
358 |
+ |
|
359 |
+ ASSERT (ciphername); |
|
360 |
+ |
|
361 |
+ cipher = mbedtls_cipher_info_from_string(ciphername); |
|
362 |
+ |
|
363 |
+ if (NULL == cipher) |
|
364 |
+ msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername); |
|
365 |
+ |
|
366 |
+ if (cipher->key_bitlen/8 > MAX_CIPHER_KEY_LENGTH) |
|
367 |
+ msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)", |
|
368 |
+ ciphername, |
|
369 |
+ cipher->key_bitlen/8, |
|
370 |
+ MAX_CIPHER_KEY_LENGTH); |
|
371 |
+ |
|
372 |
+ return cipher; |
|
373 |
+} |
|
374 |
+ |
|
375 |
+const char * |
|
376 |
+cipher_kt_name (const mbedtls_cipher_info_t *cipher_kt) |
|
377 |
+{ |
|
378 |
+ if (NULL == cipher_kt) |
|
379 |
+ return "[null-cipher]"; |
|
380 |
+ |
|
381 |
+ return translate_cipher_name_to_openvpn(cipher_kt->name); |
|
382 |
+} |
|
383 |
+ |
|
384 |
+int |
|
385 |
+cipher_kt_key_size (const mbedtls_cipher_info_t *cipher_kt) |
|
386 |
+{ |
|
387 |
+ if (NULL == cipher_kt) |
|
388 |
+ return 0; |
|
389 |
+ |
|
390 |
+ return cipher_kt->key_bitlen/8; |
|
391 |
+} |
|
392 |
+ |
|
393 |
+int |
|
394 |
+cipher_kt_iv_size (const mbedtls_cipher_info_t *cipher_kt) |
|
395 |
+{ |
|
396 |
+ if (NULL == cipher_kt) |
|
397 |
+ return 0; |
|
398 |
+ return cipher_kt->iv_size; |
|
399 |
+} |
|
400 |
+ |
|
401 |
+int |
|
402 |
+cipher_kt_block_size (const mbedtls_cipher_info_t *cipher_kt) |
|
403 |
+{ |
|
404 |
+ if (NULL == cipher_kt) |
|
405 |
+ return 0; |
|
406 |
+ return cipher_kt->block_size; |
|
407 |
+} |
|
408 |
+ |
|
409 |
+int |
|
410 |
+cipher_kt_tag_size (const mbedtls_cipher_info_t *cipher_kt) |
|
411 |
+{ |
|
412 |
+#ifdef HAVE_AEAD_CIPHER_MODES |
|
413 |
+ if (cipher_kt && cipher_kt_mode_aead(cipher_kt)) |
|
414 |
+ return OPENVPN_AEAD_TAG_LENGTH; |
|
415 |
+#endif |
|
416 |
+ return 0; |
|
417 |
+} |
|
418 |
+ |
|
419 |
+int |
|
420 |
+cipher_kt_mode (const mbedtls_cipher_info_t *cipher_kt) |
|
421 |
+{ |
|
422 |
+ ASSERT(NULL != cipher_kt); |
|
423 |
+ return cipher_kt->mode; |
|
424 |
+} |
|
425 |
+ |
|
426 |
+bool |
|
427 |
+cipher_kt_mode_cbc(const cipher_kt_t *cipher) |
|
428 |
+{ |
|
429 |
+ return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC; |
|
430 |
+} |
|
431 |
+ |
|
432 |
+bool |
|
433 |
+cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher) |
|
434 |
+{ |
|
435 |
+ return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB || |
|
436 |
+ cipher_kt_mode(cipher) == OPENVPN_MODE_CFB); |
|
437 |
+} |
|
438 |
+ |
|
439 |
+bool |
|
440 |
+cipher_kt_mode_aead(const cipher_kt_t *cipher) |
|
441 |
+{ |
|
442 |
+ return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_GCM; |
|
443 |
+} |
|
444 |
+ |
|
445 |
+ |
|
446 |
+/* |
|
447 |
+ * |
|
448 |
+ * Generic cipher context functions |
|
449 |
+ * |
|
450 |
+ */ |
|
451 |
+ |
|
452 |
+ |
|
453 |
+void |
|
454 |
+cipher_ctx_init (mbedtls_cipher_context_t *ctx, uint8_t *key, int key_len, |
|
455 |
+ const mbedtls_cipher_info_t *kt, const mbedtls_operation_t operation) |
|
456 |
+{ |
|
457 |
+ ASSERT(NULL != kt && NULL != ctx); |
|
458 |
+ |
|
459 |
+ CLEAR (*ctx); |
|
460 |
+ |
|
461 |
+ if (!mbed_ok(mbedtls_cipher_setup(ctx, kt))) |
|
462 |
+ msg (M_FATAL, "mbed TLS cipher context init #1"); |
|
463 |
+ |
|
464 |
+ if (!mbed_ok(mbedtls_cipher_setkey(ctx, key, key_len*8, operation))) |
|
465 |
+ msg (M_FATAL, "mbed TLS cipher set key"); |
|
466 |
+ |
|
467 |
+ /* make sure we used a big enough key */ |
|
468 |
+ ASSERT (ctx->key_bitlen <= key_len*8); |
|
469 |
+} |
|
470 |
+ |
|
471 |
+void cipher_ctx_cleanup (mbedtls_cipher_context_t *ctx) |
|
472 |
+{ |
|
473 |
+ mbedtls_cipher_free(ctx); |
|
474 |
+} |
|
475 |
+ |
|
476 |
+int cipher_ctx_iv_length (const mbedtls_cipher_context_t *ctx) |
|
477 |
+{ |
|
478 |
+ return mbedtls_cipher_get_iv_size(ctx); |
|
479 |
+} |
|
480 |
+ |
|
481 |
+int cipher_ctx_get_tag (cipher_ctx_t *ctx, uint8_t* tag, int tag_len) |
|
482 |
+{ |
|
483 |
+#ifdef HAVE_AEAD_CIPHER_MODES |
|
484 |
+ if (tag_len > SIZE_MAX) |
|
485 |
+ return 0; |
|
486 |
+ |
|
487 |
+ if (!mbed_ok (mbedtls_cipher_write_tag (ctx, (unsigned char *) tag, tag_len))) |
|
488 |
+ return 0; |
|
489 |
+ |
|
490 |
+ return 1; |
|
491 |
+#else |
|
492 |
+ ASSERT(0); |
|
493 |
+#endif /* HAVE_AEAD_CIPHER_MODES */ |
|
494 |
+} |
|
495 |
+ |
|
496 |
+int cipher_ctx_block_size(const mbedtls_cipher_context_t *ctx) |
|
497 |
+{ |
|
498 |
+ return mbedtls_cipher_get_block_size(ctx); |
|
499 |
+} |
|
500 |
+ |
|
501 |
+int cipher_ctx_mode (const mbedtls_cipher_context_t *ctx) |
|
502 |
+{ |
|
503 |
+ ASSERT(NULL != ctx); |
|
504 |
+ |
|
505 |
+ return cipher_kt_mode(ctx->cipher_info); |
|
506 |
+} |
|
507 |
+ |
|
508 |
+const cipher_kt_t * |
|
509 |
+cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx) |
|
510 |
+{ |
|
511 |
+ return ctx ? ctx->cipher_info : NULL; |
|
512 |
+} |
|
513 |
+ |
|
514 |
+int cipher_ctx_reset (mbedtls_cipher_context_t *ctx, uint8_t *iv_buf) |
|
515 |
+{ |
|
516 |
+ if (!mbed_ok(mbedtls_cipher_reset(ctx))) |
|
517 |
+ return 0; |
|
518 |
+ |
|
519 |
+ if (!mbed_ok(mbedtls_cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size))) |
|
520 |
+ return 0; |
|
521 |
+ |
|
522 |
+ return 1; |
|
523 |
+} |
|
524 |
+ |
|
525 |
+int cipher_ctx_update_ad (cipher_ctx_t *ctx, const uint8_t *src, int src_len) |
|
526 |
+{ |
|
527 |
+#ifdef HAVE_AEAD_CIPHER_MODES |
|
528 |
+ if (src_len > SIZE_MAX) |
|
529 |
+ return 0; |
|
530 |
+ |
|
531 |
+ if (!mbed_ok (mbedtls_cipher_update_ad (ctx, src, src_len))) |
|
532 |
+ return 0; |
|
533 |
+ |
|
534 |
+ return 1; |
|
535 |
+#else |
|
536 |
+ ASSERT(0); |
|
537 |
+#endif /* HAVE_AEAD_CIPHER_MODES */ |
|
538 |
+} |
|
539 |
+ |
|
540 |
+int cipher_ctx_update (mbedtls_cipher_context_t *ctx, uint8_t *dst, |
|
541 |
+ int *dst_len, uint8_t *src, int src_len) |
|
542 |
+{ |
|
543 |
+ size_t s_dst_len = *dst_len; |
|
544 |
+ |
|
545 |
+ if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t) src_len, dst, |
|
546 |
+ &s_dst_len))) |
|
547 |
+ return 0; |
|
548 |
+ |
|
549 |
+ *dst_len = s_dst_len; |
|
550 |
+ |
|
551 |
+ return 1; |
|
552 |
+} |
|
553 |
+ |
|
554 |
+int cipher_ctx_final (mbedtls_cipher_context_t *ctx, uint8_t *dst, int *dst_len) |
|
555 |
+{ |
|
556 |
+ size_t s_dst_len = *dst_len; |
|
557 |
+ |
|
558 |
+ if (!mbed_ok(mbedtls_cipher_finish(ctx, dst, &s_dst_len))) |
|
559 |
+ return 0; |
|
560 |
+ |
|
561 |
+ *dst_len = s_dst_len; |
|
562 |
+ |
|
563 |
+ return 1; |
|
564 |
+} |
|
565 |
+ |
|
566 |
+int cipher_ctx_final_check_tag (mbedtls_cipher_context_t *ctx, uint8_t *dst, |
|
567 |
+ int *dst_len, uint8_t *tag, size_t tag_len) |
|
568 |
+{ |
|
569 |
+#ifdef HAVE_AEAD_CIPHER_MODES |
|
570 |
+ size_t olen = 0; |
|
571 |
+ |
|
572 |
+ if (MBEDTLS_DECRYPT != ctx->operation) |
|
573 |
+ return 0; |
|
574 |
+ |
|
575 |
+ if (tag_len > SIZE_MAX) |
|
576 |
+ return 0; |
|
577 |
+ |
|
578 |
+ if (!mbed_ok (mbedtls_cipher_finish (ctx, dst, &olen))) |
|
579 |
+ { |
|
580 |
+ msg (D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__); |
|
581 |
+ return 0; |
|
582 |
+ } |
|
583 |
+ |
|
584 |
+ if (olen > INT_MAX) |
|
585 |
+ return 0; |
|
586 |
+ *dst_len = olen; |
|
587 |
+ |
|
588 |
+ if (!mbed_ok (mbedtls_cipher_check_tag (ctx, (const unsigned char *) tag, |
|
589 |
+ tag_len))) |
|
590 |
+ return 0; |
|
591 |
+ |
|
592 |
+ return 1; |
|
593 |
+#else |
|
594 |
+ ASSERT(0); |
|
595 |
+#endif /* HAVE_AEAD_CIPHER_MODES */ |
|
596 |
+} |
|
597 |
+ |
|
598 |
+void |
|
599 |
+cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH], |
|
600 |
+ unsigned char *src, |
|
601 |
+ unsigned char *dst) |
|
602 |
+{ |
|
603 |
+ mbedtls_des_context ctx; |
|
604 |
+ |
|
605 |
+ ASSERT (mbed_ok(mbedtls_des_setkey_enc(&ctx, key))); |
|
606 |
+ ASSERT (mbed_ok(mbedtls_des_crypt_ecb(&ctx, src, dst))); |
|
607 |
+} |
|
608 |
+ |
|
609 |
+ |
|
610 |
+ |
|
611 |
+/* |
|
612 |
+ * |
|
613 |
+ * Generic message digest information functions |
|
614 |
+ * |
|
615 |
+ */ |
|
616 |
+ |
|
617 |
+ |
|
618 |
+const mbedtls_md_info_t * |
|
619 |
+md_kt_get (const char *digest) |
|
620 |
+{ |
|
621 |
+ const mbedtls_md_info_t *md = NULL; |
|
622 |
+ ASSERT (digest); |
|
623 |
+ |
|
624 |
+ md = mbedtls_md_info_from_string(digest); |
|
625 |
+ if (!md) |
|
626 |
+ msg (M_FATAL, "Message hash algorithm '%s' not found", digest); |
|
627 |
+ if (mbedtls_md_get_size(md) > MAX_HMAC_KEY_LENGTH) |
|
628 |
+ msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)", |
|
629 |
+ digest, |
|
630 |
+ mbedtls_md_get_size(md), |
|
631 |
+ MAX_HMAC_KEY_LENGTH); |
|
632 |
+ return md; |
|
633 |
+} |
|
634 |
+ |
|
635 |
+const char * |
|
636 |
+md_kt_name (const mbedtls_md_info_t *kt) |
|
637 |
+{ |
|
638 |
+ if (NULL == kt) |
|
639 |
+ return "[null-digest]"; |
|
640 |
+ return mbedtls_md_get_name (kt); |
|
641 |
+} |
|
642 |
+ |
|
643 |
+int |
|
644 |
+md_kt_size (const mbedtls_md_info_t *kt) |
|
645 |
+{ |
|
646 |
+ if (NULL == kt) |
|
647 |
+ return 0; |
|
648 |
+ return mbedtls_md_get_size(kt); |
|
649 |
+} |
|
650 |
+ |
|
651 |
+/* |
|
652 |
+ * |
|
653 |
+ * Generic message digest functions |
|
654 |
+ * |
|
655 |
+ */ |
|
656 |
+ |
|
657 |
+int |
|
658 |
+md_full (const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst) |
|
659 |
+{ |
|
660 |
+ return 0 == mbedtls_md(kt, src, src_len, dst); |
|
661 |
+} |
|
662 |
+ |
|
663 |
+ |
|
664 |
+void |
|
665 |
+md_ctx_init (mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt) |
|
666 |
+{ |
|
667 |
+ ASSERT(NULL != ctx && NULL != kt); |
|
668 |
+ |
|
669 |
+ mbedtls_md_init(ctx); |
|
670 |
+ ASSERT(0 == mbedtls_md_setup(ctx, kt, 0)); |
|
671 |
+ ASSERT(0 == mbedtls_md_starts(ctx)); |
|
672 |
+} |
|
673 |
+ |
|
674 |
+void |
|
675 |
+md_ctx_cleanup(mbedtls_md_context_t *ctx) |
|
676 |
+{ |
|
677 |
+} |
|
678 |
+ |
|
679 |
+int |
|
680 |
+md_ctx_size (const mbedtls_md_context_t *ctx) |
|
681 |
+{ |
|
682 |
+ if (NULL == ctx) |
|
683 |
+ return 0; |
|
684 |
+ return mbedtls_md_get_size(ctx->md_info); |
|
685 |
+} |
|
686 |
+ |
|
687 |
+void |
|
688 |
+md_ctx_update (mbedtls_md_context_t *ctx, const uint8_t *src, int src_len) |
|
689 |
+{ |
|
690 |
+ ASSERT(0 == mbedtls_md_update(ctx, src, src_len)); |
|
691 |
+} |
|
692 |
+ |
|
693 |
+void |
|
694 |
+md_ctx_final (mbedtls_md_context_t *ctx, uint8_t *dst) |
|
695 |
+{ |
|
696 |
+ ASSERT(0 == mbedtls_md_finish(ctx, dst)); |
|
697 |
+ mbedtls_md_free(ctx); |
|
698 |
+} |
|
699 |
+ |
|
700 |
+ |
|
701 |
+/* |
|
702 |
+ * |
|
703 |
+ * Generic HMAC functions |
|
704 |
+ * |
|
705 |
+ */ |
|
706 |
+ |
|
707 |
+ |
|
708 |
+/* |
|
709 |
+ * TODO: re-enable dmsg for crypto debug |
|
710 |
+ */ |
|
711 |
+void |
|
712 |
+hmac_ctx_init (mbedtls_md_context_t *ctx, const uint8_t *key, int key_len, |
|
713 |
+ const mbedtls_md_info_t *kt) |
|
714 |
+{ |
|
715 |
+ ASSERT(NULL != kt && NULL != ctx); |
|
716 |
+ |
|
717 |
+ mbedtls_md_init(ctx); |
|
718 |
+ ASSERT(0 == mbedtls_md_setup(ctx, kt, 1)); |
|
719 |
+ ASSERT(0 == mbedtls_md_hmac_starts(ctx, key, key_len)); |
|
720 |
+ |
|
721 |
+ /* make sure we used a big enough key */ |
|
722 |
+ ASSERT (mbedtls_md_get_size(kt) <= key_len); |
|
723 |
+} |
|
724 |
+ |
|
725 |
+void |
|
726 |
+hmac_ctx_cleanup(mbedtls_md_context_t *ctx) |
|
727 |
+{ |
|
728 |
+ mbedtls_md_free(ctx); |
|
729 |
+} |
|
730 |
+ |
|
731 |
+int |
|
732 |
+hmac_ctx_size (const mbedtls_md_context_t *ctx) |
|
733 |
+{ |
|
734 |
+ if (NULL == ctx) |
|
735 |
+ return 0; |
|
736 |
+ return mbedtls_md_get_size(ctx->md_info); |
|
737 |
+} |
|
738 |
+ |
|
739 |
+void |
|
740 |
+hmac_ctx_reset (mbedtls_md_context_t *ctx) |
|
741 |
+{ |
|
742 |
+ ASSERT(0 == mbedtls_md_hmac_reset(ctx)); |
|
743 |
+} |
|
744 |
+ |
|
745 |
+void |
|
746 |
+hmac_ctx_update (mbedtls_md_context_t *ctx, const uint8_t *src, int src_len) |
|
747 |
+{ |
|
748 |
+ ASSERT(0 == mbedtls_md_hmac_update(ctx, src, src_len)); |
|
749 |
+} |
|
750 |
+ |
|
751 |
+void |
|
752 |
+hmac_ctx_final (mbedtls_md_context_t *ctx, uint8_t *dst) |
|
753 |
+{ |
|
754 |
+ ASSERT(0 == mbedtls_md_hmac_finish(ctx, dst)); |
|
755 |
+} |
|
756 |
+ |
|
757 |
+#endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_MBEDTLS */ |
0 | 758 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,146 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
9 |
+ * |
|
10 |
+ * This program is free software; you can redistribute it and/or modify |
|
11 |
+ * it under the terms of the GNU General Public License version 2 |
|
12 |
+ * as published by the Free Software Foundation. |
|
13 |
+ * |
|
14 |
+ * This program is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 |
+ * GNU General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU General Public License |
|
20 |
+ * along with this program (see the file COPYING included with this |
|
21 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
22 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
23 |
+ */ |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @file Data Channel Cryptography mbed TLS-specific backend interface |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+#ifndef CRYPTO_MBEDTLS_H_ |
|
30 |
+#define CRYPTO_MBEDTLS_H_ |
|
31 |
+ |
|
32 |
+#include <mbedtls/cipher.h> |
|
33 |
+#include <mbedtls/md.h> |
|
34 |
+#include <mbedtls/ctr_drbg.h> |
|
35 |
+ |
|
36 |
+/** Generic cipher key type %context. */ |
|
37 |
+typedef mbedtls_cipher_info_t cipher_kt_t; |
|
38 |
+ |
|
39 |
+/** Generic message digest key type %context. */ |
|
40 |
+typedef mbedtls_md_info_t md_kt_t; |
|
41 |
+ |
|
42 |
+/** Generic cipher %context. */ |
|
43 |
+typedef mbedtls_cipher_context_t cipher_ctx_t; |
|
44 |
+ |
|
45 |
+/** Generic message digest %context. */ |
|
46 |
+typedef mbedtls_md_context_t md_ctx_t; |
|
47 |
+ |
|
48 |
+/** Generic HMAC %context. */ |
|
49 |
+typedef mbedtls_md_context_t hmac_ctx_t; |
|
50 |
+ |
|
51 |
+/** Maximum length of an IV */ |
|
52 |
+#define OPENVPN_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH |
|
53 |
+ |
|
54 |
+/** Cipher is in CBC mode */ |
|
55 |
+#define OPENVPN_MODE_CBC MBEDTLS_MODE_CBC |
|
56 |
+ |
|
57 |
+/** Cipher is in OFB mode */ |
|
58 |
+#define OPENVPN_MODE_OFB MBEDTLS_MODE_OFB |
|
59 |
+ |
|
60 |
+/** Cipher is in CFB mode */ |
|
61 |
+#define OPENVPN_MODE_CFB MBEDTLS_MODE_CFB |
|
62 |
+ |
|
63 |
+/** Cipher is in GCM mode */ |
|
64 |
+#define OPENVPN_MODE_GCM MBEDTLS_MODE_GCM |
|
65 |
+ |
|
66 |
+/** Cipher should encrypt */ |
|
67 |
+#define OPENVPN_OP_ENCRYPT MBEDTLS_ENCRYPT |
|
68 |
+ |
|
69 |
+/** Cipher should decrypt */ |
|
70 |
+#define OPENVPN_OP_DECRYPT MBEDTLS_DECRYPT |
|
71 |
+ |
|
72 |
+#define MD4_DIGEST_LENGTH 16 |
|
73 |
+#define MD5_DIGEST_LENGTH 16 |
|
74 |
+#define SHA_DIGEST_LENGTH 20 |
|
75 |
+#define DES_KEY_LENGTH 8 |
|
76 |
+ |
|
77 |
+/** |
|
78 |
+ * Returns a singleton instance of the mbed TLS random number generator. |
|
79 |
+ * |
|
80 |
+ * For PolarSSL/mbed TLS 1.1+, this is the CTR_DRBG random number generator. If it |
|
81 |
+ * hasn't been initialised yet, the RNG will be initialised using the default |
|
82 |
+ * entropy sources. Aside from the default platform entropy sources, an |
|
83 |
+ * additional entropy source, the HAVEGE random number generator will also be |
|
84 |
+ * added. During initialisation, a personalisation string will be added based |
|
85 |
+ * on the time, the PID, and a pointer to the random context. |
|
86 |
+ */ |
|
87 |
+mbedtls_ctr_drbg_context *rand_ctx_get(); |
|
88 |
+ |
|
89 |
+#ifdef ENABLE_PREDICTION_RESISTANCE |
|
90 |
+/** |
|
91 |
+ * Enable prediction resistance on the random number generator. |
|
92 |
+ */ |
|
93 |
+void rand_ctx_enable_prediction_resistance(); |
|
94 |
+#endif |
|
95 |
+ |
|
96 |
+/** |
|
97 |
+ * Log the supplied mbed TLS error, prefixed by supplied prefix. |
|
98 |
+ * |
|
99 |
+ * @param flags Flags to indicate error type and priority. |
|
100 |
+ * @param errval mbed TLS error code to convert to error message. |
|
101 |
+ * @param prefix Prefix to mbed TLS error message. |
|
102 |
+ * |
|
103 |
+ * @returns true if no errors are detected, false otherwise. |
|
104 |
+ */ |
|
105 |
+bool mbed_log_err(unsigned int flags, int errval, const char *prefix); |
|
106 |
+ |
|
107 |
+/** |
|
108 |
+ * Log the supplied mbed TLS error, prefixed by function name and line number. |
|
109 |
+ * |
|
110 |
+ * @param flags Flags to indicate error type and priority. |
|
111 |
+ * @param errval mbed TLS error code to convert to error message. |
|
112 |
+ * @param func Function name where error was reported. |
|
113 |
+ * @param line Line number where error was reported. |
|
114 |
+ * |
|
115 |
+ * @returns true if no errors are detected, false otherwise. |
|
116 |
+ */ |
|
117 |
+bool mbed_log_func_line(unsigned int flags, int errval, const char *func, |
|
118 |
+ int line); |
|
119 |
+ |
|
120 |
+/** Wraps mbed_log_func_line() to prevent function calls for non-errors */ |
|
121 |
+static inline bool mbed_log_func_line_lite(unsigned int flags, int errval, |
|
122 |
+ const char *func, int line) { |
|
123 |
+ if (errval) { |
|
124 |
+ return mbed_log_func_line (flags, errval, func, line); |
|
125 |
+ } |
|
126 |
+ return true; |
|
127 |
+} |
|
128 |
+ |
|
129 |
+/** |
|
130 |
+ * Check errval and log on error. |
|
131 |
+ * |
|
132 |
+ * Convenience wrapper to put around mbed TLS library calls, e.g. |
|
133 |
+ * if (!mbed_ok (mbedtls_ssl_func())) return 0; |
|
134 |
+ * or |
|
135 |
+ * ASSERT (mbed_ok (mbedtls_ssl_func())); |
|
136 |
+ * |
|
137 |
+ * @param errval mbed TLS error code to convert to error message. |
|
138 |
+ * |
|
139 |
+ * @returns true if no errors are detected, false otherwise. |
|
140 |
+ */ |
|
141 |
+#define mbed_ok(errval) \ |
|
142 |
+ mbed_log_func_line_lite(D_CRYPT_ERRORS, errval, __func__, __LINE__) |
|
143 |
+ |
|
144 |
+ |
|
145 |
+#endif /* CRYPTO_MBEDTLS_H_ */ |
0 | 146 |
deleted file mode 100644 |
... | ... |
@@ -1,758 +0,0 @@ |
1 |
-/* |
|
2 |
- * OpenVPN -- An application to securely tunnel IP networks |
|
3 |
- * over a single TCP/UDP port, with support for SSL/TLS-based |
|
4 |
- * session authentication and key exchange, |
|
5 |
- * packet encryption, packet authentication, and |
|
6 |
- * packet compression. |
|
7 |
- * |
|
8 |
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
9 |
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
10 |
- * |
|
11 |
- * This program is free software; you can redistribute it and/or modify |
|
12 |
- * it under the terms of the GNU General Public License version 2 |
|
13 |
- * as published by the Free Software Foundation. |
|
14 |
- * |
|
15 |
- * This program is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
- * GNU General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU General Public License |
|
21 |
- * along with this program (see the file COPYING included with this |
|
22 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
23 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
- */ |
|
25 |
- |
|
26 |
-/** |
|
27 |
- * @file Data Channel Cryptography mbed TLS-specific backend interface |
|
28 |
- */ |
|
29 |
- |
|
30 |
-#ifdef HAVE_CONFIG_H |
|
31 |
-#include "config.h" |
|
32 |
-#elif defined(_MSC_VER) |
|
33 |
-#include "config-msvc.h" |
|
34 |
-#endif |
|
35 |
- |
|
36 |
-#include "syshead.h" |
|
37 |
- |
|
38 |
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
39 |
- |
|
40 |
-#include "errlevel.h" |
|
41 |
-#include "basic.h" |
|
42 |
-#include "buffer.h" |
|
43 |
-#include "integer.h" |
|
44 |
-#include "crypto_backend.h" |
|
45 |
-#include "otime.h" |
|
46 |
-#include "misc.h" |
|
47 |
- |
|
48 |
-#include <mbedtls/des.h> |
|
49 |
-#include <mbedtls/error.h> |
|
50 |
-#include <mbedtls/md5.h> |
|
51 |
-#include <mbedtls/cipher.h> |
|
52 |
-#include <mbedtls/havege.h> |
|
53 |
- |
|
54 |
-#include <mbedtls/entropy.h> |
|
55 |
- |
|
56 |
- |
|
57 |
-/* |
|
58 |
- * |
|
59 |
- * Hardware engine support. Allows loading/unloading of engines. |
|
60 |
- * |
|
61 |
- */ |
|
62 |
- |
|
63 |
-void |
|
64 |
-crypto_init_lib_engine (const char *engine_name) |
|
65 |
-{ |
|
66 |
- msg (M_WARN, "Note: mbed TLS hardware crypto engine functionality is not " |
|
67 |
- "available"); |
|
68 |
-} |
|
69 |
- |
|
70 |
-/* |
|
71 |
- * |
|
72 |
- * Functions related to the core crypto library |
|
73 |
- * |
|
74 |
- */ |
|
75 |
- |
|
76 |
-void |
|
77 |
-crypto_init_lib (void) |
|
78 |
-{ |
|
79 |
-} |
|
80 |
- |
|
81 |
-void |
|
82 |
-crypto_uninit_lib (void) |
|
83 |
-{ |
|
84 |
-} |
|
85 |
- |
|
86 |
-void |
|
87 |
-crypto_clear_error (void) |
|
88 |
-{ |
|
89 |
-} |
|
90 |
- |
|
91 |
-bool mbed_log_err(unsigned int flags, int errval, const char *prefix) |
|
92 |
-{ |
|
93 |
- if (0 != errval) |
|
94 |
- { |
|
95 |
- char errstr[256]; |
|
96 |
- mbedtls_strerror(errval, errstr, sizeof(errstr)); |
|
97 |
- |
|
98 |
- if (NULL == prefix) prefix = "mbed TLS error"; |
|
99 |
- msg (flags, "%s: %s", prefix, errstr); |
|
100 |
- } |
|
101 |
- |
|
102 |
- return 0 == errval; |
|
103 |
-} |
|
104 |
- |
|
105 |
-bool mbed_log_func_line(unsigned int flags, int errval, const char *func, |
|
106 |
- int line) |
|
107 |
-{ |
|
108 |
- char prefix[256]; |
|
109 |
- |
|
110 |
- if (!openvpn_snprintf(prefix, sizeof(prefix), "%s:%d", func, line)) |
|
111 |
- return mbed_log_err(flags, errval, func); |
|
112 |
- |
|
113 |
- return mbed_log_err(flags, errval, prefix); |
|
114 |
-} |
|
115 |
- |
|
116 |
- |
|
117 |
-#ifdef DMALLOC |
|
118 |
-void |
|
119 |
-crypto_init_dmalloc (void) |
|
120 |
-{ |
|
121 |
- msg (M_ERR, "Error: dmalloc support is not available for mbed TLS."); |
|
122 |
-} |
|
123 |
-#endif /* DMALLOC */ |
|
124 |
- |
|
125 |
-const cipher_name_pair cipher_name_translation_table[] = { |
|
126 |
- { "BF-CBC", "BLOWFISH-CBC" }, |
|
127 |
- { "BF-CFB", "BLOWFISH-CFB64" }, |
|
128 |
- { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" }, |
|
129 |
- { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" }, |
|
130 |
- { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" } |
|
131 |
-}; |
|
132 |
-const size_t cipher_name_translation_table_count = |
|
133 |
- sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table); |
|
134 |
- |
|
135 |
-void |
|
136 |
-show_available_ciphers () |
|
137 |
-{ |
|
138 |
- const int *ciphers = mbedtls_cipher_list(); |
|
139 |
- |
|
140 |
-#ifndef ENABLE_SMALL |
|
141 |
- printf ("The following ciphers and cipher modes are available for use\n" |
|
142 |
- "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n" |
|
143 |
- "parameter to the --cipher option. Using a CBC or GCM mode is\n" |
|
144 |
- "recommended. In static key mode only CBC mode is allowed.\n\n"); |
|
145 |
-#endif |
|
146 |
- |
|
147 |
- while (*ciphers != 0) |
|
148 |
- { |
|
149 |
- const cipher_kt_t *info = mbedtls_cipher_info_from_type(*ciphers); |
|
150 |
- |
|
151 |
- if (info && (cipher_kt_mode_cbc(info) |
|
152 |
-#ifdef HAVE_AEAD_CIPHER_MODES |
|
153 |
- || cipher_kt_mode_aead(info) |
|
154 |
-#endif |
|
155 |
- )) |
|
156 |
- { |
|
157 |
- const char *ssl_only = cipher_kt_mode_cbc(info) ? |
|
158 |
- "" : " (TLS client/server mode)"; |
|
159 |
- |
|
160 |
- printf ("%s %d bit default key%s\n", |
|
161 |
- cipher_kt_name(info), cipher_kt_key_size(info) * 8, ssl_only); |
|
162 |
- } |
|
163 |
- |
|
164 |
- ciphers++; |
|
165 |
- } |
|
166 |
- printf ("\n"); |
|
167 |
-} |
|
168 |
- |
|
169 |
-void |
|
170 |
-show_available_digests () |
|
171 |
-{ |
|
172 |
- const int *digests = mbedtls_md_list(); |
|
173 |
- |
|
174 |
-#ifndef ENABLE_SMALL |
|
175 |
- printf ("The following message digests are available for use with\n" |
|
176 |
- PACKAGE_NAME ". A message digest is used in conjunction with\n" |
|
177 |
- "the HMAC function, to authenticate received packets.\n" |
|
178 |
- "You can specify a message digest as parameter to\n" |
|
179 |
- "the --auth option.\n\n"); |
|
180 |
-#endif |
|
181 |
- |
|
182 |
- while (*digests != 0) |
|
183 |
- { |
|
184 |
- const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests); |
|
185 |
- |
|
186 |
- if (info) |
|
187 |
- printf ("%s %d bit default key\n", mbedtls_md_get_name(info), |
|
188 |
- mbedtls_md_get_size(info) * 8); |
|
189 |
- digests++; |
|
190 |
- } |
|
191 |
- printf ("\n"); |
|
192 |
-} |
|
193 |
- |
|
194 |
-void |
|
195 |
-show_available_engines () |
|
196 |
-{ |
|
197 |
- printf ("Sorry, mbed TLS hardware crypto engine functionality is not " |
|
198 |
- "available\n"); |
|
199 |
-} |
|
200 |
- |
|
201 |
-/* |
|
202 |
- * |
|
203 |
- * Random number functions, used in cases where we want |
|
204 |
- * reasonably strong cryptographic random number generation |
|
205 |
- * without depleting our entropy pool. Used for random |
|
206 |
- * IV values and a number of other miscellaneous tasks. |
|
207 |
- * |
|
208 |
- */ |
|
209 |
- |
|
210 |
-/* |
|
211 |
- * Initialise the given ctr_drbg context, using a personalisation string and an |
|
212 |
- * entropy gathering function. |
|
213 |
- */ |
|
214 |
-mbedtls_ctr_drbg_context * rand_ctx_get() |
|
215 |
-{ |
|
216 |
- static mbedtls_entropy_context ec = {0}; |
|
217 |
- static mbedtls_ctr_drbg_context cd_ctx = {0}; |
|
218 |
- static bool rand_initialised = false; |
|
219 |
- |
|
220 |
- if (!rand_initialised) |
|
221 |
- { |
|
222 |
- struct gc_arena gc = gc_new(); |
|
223 |
- struct buffer pers_string = alloc_buf_gc(100, &gc); |
|
224 |
- |
|
225 |
- /* |
|
226 |
- * Personalisation string, should be as unique as possible (see NIST |
|
227 |
- * 800-90 section 8.7.1). We have very little information at this stage. |
|
228 |
- * Include Program Name, memory address of the context and PID. |
|
229 |
- */ |
|
230 |
- buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc)); |
|
231 |
- |
|
232 |
- /* Initialise mbed TLS RNG, and built-in entropy sources */ |
|
233 |
- mbedtls_entropy_init(&ec); |
|
234 |
- |
|
235 |
- mbedtls_ctr_drbg_init(&cd_ctx); |
|
236 |
- if (!mbed_ok(mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec, |
|
237 |
- BPTR(&pers_string), BLEN(&pers_string)))) |
|
238 |
- msg (M_FATAL, "Failed to initialize random generator"); |
|
239 |
- |
|
240 |
- gc_free(&gc); |
|
241 |
- rand_initialised = true; |
|
242 |
- } |
|
243 |
- |
|
244 |
- return &cd_ctx; |
|
245 |
-} |
|
246 |
- |
|
247 |
-#ifdef ENABLE_PREDICTION_RESISTANCE |
|
248 |
-void rand_ctx_enable_prediction_resistance() |
|
249 |
-{ |
|
250 |
- mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get(); |
|
251 |
- |
|
252 |
- mbedtls_ctr_drbg_set_prediction_resistance(cd_ctx, 1); |
|
253 |
-} |
|
254 |
-#endif /* ENABLE_PREDICTION_RESISTANCE */ |
|
255 |
- |
|
256 |
-int |
|
257 |
-rand_bytes (uint8_t *output, int len) |
|
258 |
-{ |
|
259 |
- mbedtls_ctr_drbg_context *rng_ctx = rand_ctx_get(); |
|
260 |
- |
|
261 |
- while (len > 0) |
|
262 |
- { |
|
263 |
- const size_t blen = min_int (len, MBEDTLS_CTR_DRBG_MAX_REQUEST); |
|
264 |
- if (0 != mbedtls_ctr_drbg_random(rng_ctx, output, blen)) |
|
265 |
- return 0; |
|
266 |
- |
|
267 |
- output += blen; |
|
268 |
- len -= blen; |
|
269 |
- } |
|
270 |
- |
|
271 |
- return 1; |
|
272 |
-} |
|
273 |
- |
|
274 |
-/* |
|
275 |
- * |
|
276 |
- * Key functions, allow manipulation of keys. |
|
277 |
- * |
|
278 |
- */ |
|
279 |
- |
|
280 |
- |
|
281 |
-int |
|
282 |
-key_des_num_cblocks (const mbedtls_cipher_info_t *kt) |
|
283 |
-{ |
|
284 |
- int ret = 0; |
|
285 |
- if (kt->type == MBEDTLS_CIPHER_DES_CBC) |
|
286 |
- ret = 1; |
|
287 |
- if (kt->type == MBEDTLS_CIPHER_DES_EDE_CBC) |
|
288 |
- ret = 2; |
|
289 |
- if (kt->type == MBEDTLS_CIPHER_DES_EDE3_CBC) |
|
290 |
- ret = 3; |
|
291 |
- |
|
292 |
- dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret); |
|
293 |
- return ret; |
|
294 |
-} |
|
295 |
- |
|
296 |
-bool |
|
297 |
-key_des_check (uint8_t *key, int key_len, int ndc) |
|
298 |
-{ |
|
299 |
- int i; |
|
300 |
- struct buffer b; |
|
301 |
- |
|
302 |
- buf_set_read (&b, key, key_len); |
|
303 |
- |
|
304 |
- for (i = 0; i < ndc; ++i) |
|
305 |
- { |
|
306 |
- unsigned char *key = buf_read_alloc(&b, MBEDTLS_DES_KEY_SIZE); |
|
307 |
- if (!key) |
|
308 |
- { |
|
309 |
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material"); |
|
310 |
- goto err; |
|
311 |
- } |
|
312 |
- if (0 != mbedtls_des_key_check_weak(key)) |
|
313 |
- { |
|
314 |
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected"); |
|
315 |
- goto err; |
|
316 |
- } |
|
317 |
- if (0 != mbedtls_des_key_check_key_parity(key)) |
|
318 |
- { |
|
319 |
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected"); |
|
320 |
- goto err; |
|
321 |
- } |
|
322 |
- } |
|
323 |
- return true; |
|
324 |
- |
|
325 |
- err: |
|
326 |
- return false; |
|
327 |
-} |
|
328 |
- |
|
329 |
-void |
|
330 |
-key_des_fixup (uint8_t *key, int key_len, int ndc) |
|
331 |
-{ |
|
332 |
- int i; |
|
333 |
- struct buffer b; |
|
334 |
- |
|
335 |
- buf_set_read (&b, key, key_len); |
|
336 |
- for (i = 0; i < ndc; ++i) |
|
337 |
- { |
|
338 |
- unsigned char *key = buf_read_alloc(&b, MBEDTLS_DES_KEY_SIZE); |
|
339 |
- if (!key) |
|
340 |
- { |
|
341 |
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material"); |
|
342 |
- return; |
|
343 |
- } |
|
344 |
- mbedtls_des_key_set_parity(key); |
|
345 |
- } |
|
346 |
-} |
|
347 |
- |
|
348 |
-/* |
|
349 |
- * |
|
350 |
- * Generic cipher key type functions |
|
351 |
- * |
|
352 |
- */ |
|
353 |
- |
|
354 |
- |
|
355 |
-const mbedtls_cipher_info_t * |
|
356 |
-cipher_kt_get (const char *ciphername) |
|
357 |
-{ |
|
358 |
- const mbedtls_cipher_info_t *cipher = NULL; |
|
359 |
- |
|
360 |
- ASSERT (ciphername); |
|
361 |
- |
|
362 |
- cipher = mbedtls_cipher_info_from_string(ciphername); |
|
363 |
- |
|
364 |
- if (NULL == cipher) |
|
365 |
- msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername); |
|
366 |
- |
|
367 |
- if (cipher->key_bitlen/8 > MAX_CIPHER_KEY_LENGTH) |
|
368 |
- msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)", |
|
369 |
- ciphername, |
|
370 |
- cipher->key_bitlen/8, |
|
371 |
- MAX_CIPHER_KEY_LENGTH); |
|
372 |
- |
|
373 |
- return cipher; |
|
374 |
-} |
|
375 |
- |
|
376 |
-const char * |
|
377 |
-cipher_kt_name (const mbedtls_cipher_info_t *cipher_kt) |
|
378 |
-{ |
|
379 |
- if (NULL == cipher_kt) |
|
380 |
- return "[null-cipher]"; |
|
381 |
- |
|
382 |
- return translate_cipher_name_to_openvpn(cipher_kt->name); |
|
383 |
-} |
|
384 |
- |
|
385 |
-int |
|
386 |
-cipher_kt_key_size (const mbedtls_cipher_info_t *cipher_kt) |
|
387 |
-{ |
|
388 |
- if (NULL == cipher_kt) |
|
389 |
- return 0; |
|
390 |
- |
|
391 |
- return cipher_kt->key_bitlen/8; |
|
392 |
-} |
|
393 |
- |
|
394 |
-int |
|
395 |
-cipher_kt_iv_size (const mbedtls_cipher_info_t *cipher_kt) |
|
396 |
-{ |
|
397 |
- if (NULL == cipher_kt) |
|
398 |
- return 0; |
|
399 |
- return cipher_kt->iv_size; |
|
400 |
-} |
|
401 |
- |
|
402 |
-int |
|
403 |
-cipher_kt_block_size (const mbedtls_cipher_info_t *cipher_kt) |
|
404 |
-{ |
|
405 |
- if (NULL == cipher_kt) |
|
406 |
- return 0; |
|
407 |
- return cipher_kt->block_size; |
|
408 |
-} |
|
409 |
- |
|
410 |
-int |
|
411 |
-cipher_kt_tag_size (const mbedtls_cipher_info_t *cipher_kt) |
|
412 |
-{ |
|
413 |
-#ifdef HAVE_AEAD_CIPHER_MODES |
|
414 |
- if (cipher_kt && cipher_kt_mode_aead(cipher_kt)) |
|
415 |
- return OPENVPN_AEAD_TAG_LENGTH; |
|
416 |
-#endif |
|
417 |
- return 0; |
|
418 |
-} |
|
419 |
- |
|
420 |
-int |
|
421 |
-cipher_kt_mode (const mbedtls_cipher_info_t *cipher_kt) |
|
422 |
-{ |
|
423 |
- ASSERT(NULL != cipher_kt); |
|
424 |
- return cipher_kt->mode; |
|
425 |
-} |
|
426 |
- |
|
427 |
-bool |
|
428 |
-cipher_kt_mode_cbc(const cipher_kt_t *cipher) |
|
429 |
-{ |
|
430 |
- return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC; |
|
431 |
-} |
|
432 |
- |
|
433 |
-bool |
|
434 |
-cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher) |
|
435 |
-{ |
|
436 |
- return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB || |
|
437 |
- cipher_kt_mode(cipher) == OPENVPN_MODE_CFB); |
|
438 |
-} |
|
439 |
- |
|
440 |
-bool |
|
441 |
-cipher_kt_mode_aead(const cipher_kt_t *cipher) |
|
442 |
-{ |
|
443 |
- return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_GCM; |
|
444 |
-} |
|
445 |
- |
|
446 |
- |
|
447 |
-/* |
|
448 |
- * |
|
449 |
- * Generic cipher context functions |
|
450 |
- * |
|
451 |
- */ |
|
452 |
- |
|
453 |
- |
|
454 |
-void |
|
455 |
-cipher_ctx_init (mbedtls_cipher_context_t *ctx, uint8_t *key, int key_len, |
|
456 |
- const mbedtls_cipher_info_t *kt, const mbedtls_operation_t operation) |
|
457 |
-{ |
|
458 |
- ASSERT(NULL != kt && NULL != ctx); |
|
459 |
- |
|
460 |
- CLEAR (*ctx); |
|
461 |
- |
|
462 |
- if (!mbed_ok(mbedtls_cipher_setup(ctx, kt))) |
|
463 |
- msg (M_FATAL, "mbed TLS cipher context init #1"); |
|
464 |
- |
|
465 |
- if (!mbed_ok(mbedtls_cipher_setkey(ctx, key, key_len*8, operation))) |
|
466 |
- msg (M_FATAL, "mbed TLS cipher set key"); |
|
467 |
- |
|
468 |
- /* make sure we used a big enough key */ |
|
469 |
- ASSERT (ctx->key_bitlen <= key_len*8); |
|
470 |
-} |
|
471 |
- |
|
472 |
-void cipher_ctx_cleanup (mbedtls_cipher_context_t *ctx) |
|
473 |
-{ |
|
474 |
- mbedtls_cipher_free(ctx); |
|
475 |
-} |
|
476 |
- |
|
477 |
-int cipher_ctx_iv_length (const mbedtls_cipher_context_t *ctx) |
|
478 |
-{ |
|
479 |
- return mbedtls_cipher_get_iv_size(ctx); |
|
480 |
-} |
|
481 |
- |
|
482 |
-int cipher_ctx_get_tag (cipher_ctx_t *ctx, uint8_t* tag, int tag_len) |
|
483 |
-{ |
|
484 |
-#ifdef HAVE_AEAD_CIPHER_MODES |
|
485 |
- if (tag_len > SIZE_MAX) |
|
486 |
- return 0; |
|
487 |
- |
|
488 |
- if (!mbed_ok (mbedtls_cipher_write_tag (ctx, (unsigned char *) tag, tag_len))) |
|
489 |
- return 0; |
|
490 |
- |
|
491 |
- return 1; |
|
492 |
-#else |
|
493 |
- ASSERT(0); |
|
494 |
-#endif /* HAVE_AEAD_CIPHER_MODES */ |
|
495 |
-} |
|
496 |
- |
|
497 |
-int cipher_ctx_block_size(const mbedtls_cipher_context_t *ctx) |
|
498 |
-{ |
|
499 |
- return mbedtls_cipher_get_block_size(ctx); |
|
500 |
-} |
|
501 |
- |
|
502 |
-int cipher_ctx_mode (const mbedtls_cipher_context_t *ctx) |
|
503 |
-{ |
|
504 |
- ASSERT(NULL != ctx); |
|
505 |
- |
|
506 |
- return cipher_kt_mode(ctx->cipher_info); |
|
507 |
-} |
|
508 |
- |
|
509 |
-const cipher_kt_t * |
|
510 |
-cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx) |
|
511 |
-{ |
|
512 |
- return ctx ? ctx->cipher_info : NULL; |
|
513 |
-} |
|
514 |
- |
|
515 |
-int cipher_ctx_reset (mbedtls_cipher_context_t *ctx, uint8_t *iv_buf) |
|
516 |
-{ |
|
517 |
- if (!mbed_ok(mbedtls_cipher_reset(ctx))) |
|
518 |
- return 0; |
|
519 |
- |
|
520 |
- if (!mbed_ok(mbedtls_cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size))) |
|
521 |
- return 0; |
|
522 |
- |
|
523 |
- return 1; |
|
524 |
-} |
|
525 |
- |
|
526 |
-int cipher_ctx_update_ad (cipher_ctx_t *ctx, const uint8_t *src, int src_len) |
|
527 |
-{ |
|
528 |
-#ifdef HAVE_AEAD_CIPHER_MODES |
|
529 |
- if (src_len > SIZE_MAX) |
|
530 |
- return 0; |
|
531 |
- |
|
532 |
- if (!mbed_ok (mbedtls_cipher_update_ad (ctx, src, src_len))) |
|
533 |
- return 0; |
|
534 |
- |
|
535 |
- return 1; |
|
536 |
-#else |
|
537 |
- ASSERT(0); |
|
538 |
-#endif /* HAVE_AEAD_CIPHER_MODES */ |
|
539 |
-} |
|
540 |
- |
|
541 |
-int cipher_ctx_update (mbedtls_cipher_context_t *ctx, uint8_t *dst, |
|
542 |
- int *dst_len, uint8_t *src, int src_len) |
|
543 |
-{ |
|
544 |
- size_t s_dst_len = *dst_len; |
|
545 |
- |
|
546 |
- if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t) src_len, dst, |
|
547 |
- &s_dst_len))) |
|
548 |
- return 0; |
|
549 |
- |
|
550 |
- *dst_len = s_dst_len; |
|
551 |
- |
|
552 |
- return 1; |
|
553 |
-} |
|
554 |
- |
|
555 |
-int cipher_ctx_final (mbedtls_cipher_context_t *ctx, uint8_t *dst, int *dst_len) |
|
556 |
-{ |
|
557 |
- size_t s_dst_len = *dst_len; |
|
558 |
- |
|
559 |
- if (!mbed_ok(mbedtls_cipher_finish(ctx, dst, &s_dst_len))) |
|
560 |
- return 0; |
|
561 |
- |
|
562 |
- *dst_len = s_dst_len; |
|
563 |
- |
|
564 |
- return 1; |
|
565 |
-} |
|
566 |
- |
|
567 |
-int cipher_ctx_final_check_tag (mbedtls_cipher_context_t *ctx, uint8_t *dst, |
|
568 |
- int *dst_len, uint8_t *tag, size_t tag_len) |
|
569 |
-{ |
|
570 |
-#ifdef HAVE_AEAD_CIPHER_MODES |
|
571 |
- size_t olen = 0; |
|
572 |
- |
|
573 |
- if (MBEDTLS_DECRYPT != ctx->operation) |
|
574 |
- return 0; |
|
575 |
- |
|
576 |
- if (tag_len > SIZE_MAX) |
|
577 |
- return 0; |
|
578 |
- |
|
579 |
- if (!mbed_ok (mbedtls_cipher_finish (ctx, dst, &olen))) |
|
580 |
- { |
|
581 |
- msg (D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__); |
|
582 |
- return 0; |
|
583 |
- } |
|
584 |
- |
|
585 |
- if (olen > INT_MAX) |
|
586 |
- return 0; |
|
587 |
- *dst_len = olen; |
|
588 |
- |
|
589 |
- if (!mbed_ok (mbedtls_cipher_check_tag (ctx, (const unsigned char *) tag, |
|
590 |
- tag_len))) |
|
591 |
- return 0; |
|
592 |
- |
|
593 |
- return 1; |
|
594 |
-#else |
|
595 |
- ASSERT(0); |
|
596 |
-#endif /* HAVE_AEAD_CIPHER_MODES */ |
|
597 |
-} |
|
598 |
- |
|
599 |
-void |
|
600 |
-cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH], |
|
601 |
- unsigned char *src, |
|
602 |
- unsigned char *dst) |
|
603 |
-{ |
|
604 |
- mbedtls_des_context ctx; |
|
605 |
- |
|
606 |
- ASSERT (mbed_ok(mbedtls_des_setkey_enc(&ctx, key))); |
|
607 |
- ASSERT (mbed_ok(mbedtls_des_crypt_ecb(&ctx, src, dst))); |
|
608 |
-} |
|
609 |
- |
|
610 |
- |
|
611 |
- |
|
612 |
-/* |
|
613 |
- * |
|
614 |
- * Generic message digest information functions |
|
615 |
- * |
|
616 |
- */ |
|
617 |
- |
|
618 |
- |
|
619 |
-const mbedtls_md_info_t * |
|
620 |
-md_kt_get (const char *digest) |
|
621 |
-{ |
|
622 |
- const mbedtls_md_info_t *md = NULL; |
|
623 |
- ASSERT (digest); |
|
624 |
- |
|
625 |
- md = mbedtls_md_info_from_string(digest); |
|
626 |
- if (!md) |
|
627 |
- msg (M_FATAL, "Message hash algorithm '%s' not found", digest); |
|
628 |
- if (mbedtls_md_get_size(md) > MAX_HMAC_KEY_LENGTH) |
|
629 |
- msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)", |
|
630 |
- digest, |
|
631 |
- mbedtls_md_get_size(md), |
|
632 |
- MAX_HMAC_KEY_LENGTH); |
|
633 |
- return md; |
|
634 |
-} |
|
635 |
- |
|
636 |
-const char * |
|
637 |
-md_kt_name (const mbedtls_md_info_t *kt) |
|
638 |
-{ |
|
639 |
- if (NULL == kt) |
|
640 |
- return "[null-digest]"; |
|
641 |
- return mbedtls_md_get_name (kt); |
|
642 |
-} |
|
643 |
- |
|
644 |
-int |
|
645 |
-md_kt_size (const mbedtls_md_info_t *kt) |
|
646 |
-{ |
|
647 |
- if (NULL == kt) |
|
648 |
- return 0; |
|
649 |
- return mbedtls_md_get_size(kt); |
|
650 |
-} |
|
651 |
- |
|
652 |
-/* |
|
653 |
- * |
|
654 |
- * Generic message digest functions |
|
655 |
- * |
|
656 |
- */ |
|
657 |
- |
|
658 |
-int |
|
659 |
-md_full (const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst) |
|
660 |
-{ |
|
661 |
- return 0 == mbedtls_md(kt, src, src_len, dst); |
|
662 |
-} |
|
663 |
- |
|
664 |
- |
|
665 |
-void |
|
666 |
-md_ctx_init (mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt) |
|
667 |
-{ |
|
668 |
- ASSERT(NULL != ctx && NULL != kt); |
|
669 |
- |
|
670 |
- mbedtls_md_init(ctx); |
|
671 |
- ASSERT(0 == mbedtls_md_setup(ctx, kt, 0)); |
|
672 |
- ASSERT(0 == mbedtls_md_starts(ctx)); |
|
673 |
-} |
|
674 |
- |
|
675 |
-void |
|
676 |
-md_ctx_cleanup(mbedtls_md_context_t *ctx) |
|
677 |
-{ |
|
678 |
-} |
|
679 |
- |
|
680 |
-int |
|
681 |
-md_ctx_size (const mbedtls_md_context_t *ctx) |
|
682 |
-{ |
|
683 |
- if (NULL == ctx) |
|
684 |
- return 0; |
|
685 |
- return mbedtls_md_get_size(ctx->md_info); |
|
686 |
-} |
|
687 |
- |
|
688 |
-void |
|
689 |
-md_ctx_update (mbedtls_md_context_t *ctx, const uint8_t *src, int src_len) |
|
690 |
-{ |
|
691 |
- ASSERT(0 == mbedtls_md_update(ctx, src, src_len)); |
|
692 |
-} |
|
693 |
- |
|
694 |
-void |
|
695 |
-md_ctx_final (mbedtls_md_context_t *ctx, uint8_t *dst) |
|
696 |
-{ |
|
697 |
- ASSERT(0 == mbedtls_md_finish(ctx, dst)); |
|
698 |
- mbedtls_md_free(ctx); |
|
699 |
-} |
|
700 |
- |
|
701 |
- |
|
702 |
-/* |
|
703 |
- * |
|
704 |
- * Generic HMAC functions |
|
705 |
- * |
|
706 |
- */ |
|
707 |
- |
|
708 |
- |
|
709 |
-/* |
|
710 |
- * TODO: re-enable dmsg for crypto debug |
|
711 |
- */ |
|
712 |
-void |
|
713 |
-hmac_ctx_init (mbedtls_md_context_t *ctx, const uint8_t *key, int key_len, |
|
714 |
- const mbedtls_md_info_t *kt) |
|
715 |
-{ |
|
716 |
- ASSERT(NULL != kt && NULL != ctx); |
|
717 |
- |
|
718 |
- mbedtls_md_init(ctx); |
|
719 |
- ASSERT(0 == mbedtls_md_setup(ctx, kt, 1)); |
|
720 |
- ASSERT(0 == mbedtls_md_hmac_starts(ctx, key, key_len)); |
|
721 |
- |
|
722 |
- /* make sure we used a big enough key */ |
|
723 |
- ASSERT (mbedtls_md_get_size(kt) <= key_len); |
|
724 |
-} |
|
725 |
- |
|
726 |
-void |
|
727 |
-hmac_ctx_cleanup(mbedtls_md_context_t *ctx) |
|
728 |
-{ |
|
729 |
- mbedtls_md_free(ctx); |
|
730 |
-} |
|
731 |
- |
|
732 |
-int |
|
733 |
-hmac_ctx_size (const mbedtls_md_context_t *ctx) |
|
734 |
-{ |
|
735 |
- if (NULL == ctx) |
|
736 |
- return 0; |
|
737 |
- return mbedtls_md_get_size(ctx->md_info); |
|
738 |
-} |
|
739 |
- |
|
740 |
-void |
|
741 |
-hmac_ctx_reset (mbedtls_md_context_t *ctx) |
|
742 |
-{ |
|
743 |
- ASSERT(0 == mbedtls_md_hmac_reset(ctx)); |
|
744 |
-} |
|
745 |
- |
|
746 |
-void |
|
747 |
-hmac_ctx_update (mbedtls_md_context_t *ctx, const uint8_t *src, int src_len) |
|
748 |
-{ |
|
749 |
- ASSERT(0 == mbedtls_md_hmac_update(ctx, src, src_len)); |
|
750 |
-} |
|
751 |
- |
|
752 |
-void |
|
753 |
-hmac_ctx_final (mbedtls_md_context_t *ctx, uint8_t *dst) |
|
754 |
-{ |
|
755 |
- ASSERT(0 == mbedtls_md_hmac_finish(ctx, dst)); |
|
756 |
-} |
|
757 |
- |
|
758 |
-#endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_MBEDTLS */ |
759 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,146 +0,0 @@ |
1 |
-/* |
|
2 |
- * OpenVPN -- An application to securely tunnel IP networks |
|
3 |
- * over a single TCP/UDP port, with support for SSL/TLS-based |
|
4 |
- * session authentication and key exchange, |
|
5 |
- * packet encryption, packet authentication, and |
|
6 |
- * packet compression. |
|
7 |
- * |
|
8 |
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
9 |
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
10 |
- * |
|
11 |
- * This program is free software; you can redistribute it and/or modify |
|
12 |
- * it under the terms of the GNU General Public License version 2 |
|
13 |
- * as published by the Free Software Foundation. |
|
14 |
- * |
|
15 |
- * This program is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
- * GNU General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU General Public License |
|
21 |
- * along with this program (see the file COPYING included with this |
|
22 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
23 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
- */ |
|
25 |
- |
|
26 |
-/** |
|
27 |
- * @file Data Channel Cryptography mbed TLS-specific backend interface |
|
28 |
- */ |
|
29 |
- |
|
30 |
-#ifndef CRYPTO_MBEDTLS_H_ |
|
31 |
-#define CRYPTO_MBEDTLS_H_ |
|
32 |
- |
|
33 |
-#include <mbedtls/cipher.h> |
|
34 |
-#include <mbedtls/md.h> |
|
35 |
-#include <mbedtls/ctr_drbg.h> |
|
36 |
- |
|
37 |
-/** Generic cipher key type %context. */ |
|
38 |
-typedef mbedtls_cipher_info_t cipher_kt_t; |
|
39 |
- |
|
40 |
-/** Generic message digest key type %context. */ |
|
41 |
-typedef mbedtls_md_info_t md_kt_t; |
|
42 |
- |
|
43 |
-/** Generic cipher %context. */ |
|
44 |
-typedef mbedtls_cipher_context_t cipher_ctx_t; |
|
45 |
- |
|
46 |
-/** Generic message digest %context. */ |
|
47 |
-typedef mbedtls_md_context_t md_ctx_t; |
|
48 |
- |
|
49 |
-/** Generic HMAC %context. */ |
|
50 |
-typedef mbedtls_md_context_t hmac_ctx_t; |
|
51 |
- |
|
52 |
-/** Maximum length of an IV */ |
|
53 |
-#define OPENVPN_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH |
|
54 |
- |
|
55 |
-/** Cipher is in CBC mode */ |
|
56 |
-#define OPENVPN_MODE_CBC MBEDTLS_MODE_CBC |
|
57 |
- |
|
58 |
-/** Cipher is in OFB mode */ |
|
59 |
-#define OPENVPN_MODE_OFB MBEDTLS_MODE_OFB |
|
60 |
- |
|
61 |
-/** Cipher is in CFB mode */ |
|
62 |
-#define OPENVPN_MODE_CFB MBEDTLS_MODE_CFB |
|
63 |
- |
|
64 |
-/** Cipher is in GCM mode */ |
|
65 |
-#define OPENVPN_MODE_GCM MBEDTLS_MODE_GCM |
|
66 |
- |
|
67 |
-/** Cipher should encrypt */ |
|
68 |
-#define OPENVPN_OP_ENCRYPT MBEDTLS_ENCRYPT |
|
69 |
- |
|
70 |
-/** Cipher should decrypt */ |
|
71 |
-#define OPENVPN_OP_DECRYPT MBEDTLS_DECRYPT |
|
72 |
- |
|
73 |
-#define MD4_DIGEST_LENGTH 16 |
|
74 |
-#define MD5_DIGEST_LENGTH 16 |
|
75 |
-#define SHA_DIGEST_LENGTH 20 |
|
76 |
-#define DES_KEY_LENGTH 8 |
|
77 |
- |
|
78 |
-/** |
|
79 |
- * Returns a singleton instance of the mbed TLS random number generator. |
|
80 |
- * |
|
81 |
- * For PolarSSL/mbed TLS 1.1+, this is the CTR_DRBG random number generator. If it |
|
82 |
- * hasn't been initialised yet, the RNG will be initialised using the default |
|
83 |
- * entropy sources. Aside from the default platform entropy sources, an |
|
84 |
- * additional entropy source, the HAVEGE random number generator will also be |
|
85 |
- * added. During initialisation, a personalisation string will be added based |
|
86 |
- * on the time, the PID, and a pointer to the random context. |
|
87 |
- */ |
|
88 |
-mbedtls_ctr_drbg_context *rand_ctx_get(); |
|
89 |
- |
|
90 |
-#ifdef ENABLE_PREDICTION_RESISTANCE |
|
91 |
-/** |
|
92 |
- * Enable prediction resistance on the random number generator. |
|
93 |
- */ |
|
94 |
-void rand_ctx_enable_prediction_resistance(); |
|
95 |
-#endif |
|
96 |
- |
|
97 |
-/** |
|
98 |
- * Log the supplied mbed TLS error, prefixed by supplied prefix. |
|
99 |
- * |
|
100 |
- * @param flags Flags to indicate error type and priority. |
|
101 |
- * @param errval mbed TLS error code to convert to error message. |
|
102 |
- * @param prefix Prefix to mbed TLS error message. |
|
103 |
- * |
|
104 |
- * @returns true if no errors are detected, false otherwise. |
|
105 |
- */ |
|
106 |
-bool mbed_log_err(unsigned int flags, int errval, const char *prefix); |
|
107 |
- |
|
108 |
-/** |
|
109 |
- * Log the supplied mbed TLS error, prefixed by function name and line number. |
|
110 |
- * |
|
111 |
- * @param flags Flags to indicate error type and priority. |
|
112 |
- * @param errval mbed TLS error code to convert to error message. |
|
113 |
- * @param func Function name where error was reported. |
|
114 |
- * @param line Line number where error was reported. |
|
115 |
- * |
|
116 |
- * @returns true if no errors are detected, false otherwise. |
|
117 |
- */ |
|
118 |
-bool mbed_log_func_line(unsigned int flags, int errval, const char *func, |
|
119 |
- int line); |
|
120 |
- |
|
121 |
-/** Wraps mbed_log_func_line() to prevent function calls for non-errors */ |
|
122 |
-static inline bool mbed_log_func_line_lite(unsigned int flags, int errval, |
|
123 |
- const char *func, int line) { |
|
124 |
- if (errval) { |
|
125 |
- return mbed_log_func_line (flags, errval, func, line); |
|
126 |
- } |
|
127 |
- return true; |
|
128 |
-} |
|
129 |
- |
|
130 |
-/** |
|
131 |
- * Check errval and log on error. |
|
132 |
- * |
|
133 |
- * Convenience wrapper to put around mbed TLS library calls, e.g. |
|
134 |
- * if (!mbed_ok (mbedtls_ssl_func())) return 0; |
|
135 |
- * or |
|
136 |
- * ASSERT (mbed_ok (mbedtls_ssl_func())); |
|
137 |
- * |
|
138 |
- * @param errval mbed TLS error code to convert to error message. |
|
139 |
- * |
|
140 |
- * @returns true if no errors are detected, false otherwise. |
|
141 |
- */ |
|
142 |
-#define mbed_ok(errval) \ |
|
143 |
- mbed_log_func_line_lite(D_CRYPT_ERRORS, errval, __func__, __LINE__) |
|
144 |
- |
|
145 |
- |
|
146 |
-#endif /* CRYPTO_MBEDTLS_H_ */ |
147 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,129 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
9 |
+ * |
|
10 |
+ * This program is free software; you can redistribute it and/or modify |
|
11 |
+ * it under the terms of the GNU General Public License version 2 |
|
12 |
+ * as published by the Free Software Foundation. |
|
13 |
+ * |
|
14 |
+ * This program is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 |
+ * GNU General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU General Public License |
|
20 |
+ * along with this program (see the file COPYING included with this |
|
21 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
22 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
23 |
+ */ |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @file PKCS #11 mbed TLS backend |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+#ifdef HAVE_CONFIG_H |
|
30 |
+#include "config.h" |
|
31 |
+#elif defined(_MSC_VER) |
|
32 |
+#include "config-msvc.h" |
|
33 |
+#endif |
|
34 |
+ |
|
35 |
+#include "syshead.h" |
|
36 |
+ |
|
37 |
+#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
38 |
+ |
|
39 |
+#include "errlevel.h" |
|
40 |
+#include "pkcs11_backend.h" |
|
41 |
+#include <mbedtls/pkcs11.h> |
|
42 |
+#include <mbedtls/x509.h> |
|
43 |
+ |
|
44 |
+int |
|
45 |
+pkcs11_init_tls_session(pkcs11h_certificate_t certificate, |
|
46 |
+ struct tls_root_ctx * const ssl_ctx) |
|
47 |
+{ |
|
48 |
+ int ret = 1; |
|
49 |
+ |
|
50 |
+ ASSERT (NULL != ssl_ctx); |
|
51 |
+ |
|
52 |
+ ALLOC_OBJ_CLEAR (ssl_ctx->crt_chain, mbedtls_x509_crt); |
|
53 |
+ if (mbedtls_pkcs11_x509_cert_bind(ssl_ctx->crt_chain, certificate)) { |
|
54 |
+ msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object"); |
|
55 |
+ goto cleanup; |
|
56 |
+ } |
|
57 |
+ |
|
58 |
+ ALLOC_OBJ_CLEAR (ssl_ctx->priv_key_pkcs11, mbedtls_pkcs11_context); |
|
59 |
+ if (mbedtls_pkcs11_priv_key_bind(ssl_ctx->priv_key_pkcs11, certificate)) { |
|
60 |
+ msg (M_FATAL, "PKCS#11: Cannot initialize mbed TLS private key object"); |
|
61 |
+ goto cleanup; |
|
62 |
+ } |
|
63 |
+ |
|
64 |
+ ALLOC_OBJ_CLEAR (ssl_ctx->priv_key, mbedtls_pk_context); |
|
65 |
+ if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ssl_ctx->priv_key, |
|
66 |
+ ssl_ctx->priv_key_pkcs11, mbedtls_ssl_pkcs11_decrypt, |
|
67 |
+ mbedtls_ssl_pkcs11_sign, mbedtls_ssl_pkcs11_key_len))) { |
|
68 |
+ goto cleanup; |
|
69 |
+ } |
|
70 |
+ |
|
71 |
+ ret = 0; |
|
72 |
+ |
|
73 |
+cleanup: |
|
74 |
+ return ret; |
|
75 |
+} |
|
76 |
+ |
|
77 |
+char * |
|
78 |
+pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc) |
|
79 |
+{ |
|
80 |
+ char *ret = NULL; |
|
81 |
+ char dn[1024] = {0}; |
|
82 |
+ |
|
83 |
+ mbedtls_x509_crt mbed_crt = {0}; |
|
84 |
+ |
|
85 |
+ if (mbedtls_pkcs11_x509_cert_bind(&mbed_crt, cert)) { |
|
86 |
+ msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object"); |
|
87 |
+ goto cleanup; |
|
88 |
+ } |
|
89 |
+ |
|
90 |
+ if (-1 == mbedtls_x509_dn_gets (dn, sizeof(dn), &mbed_crt.subject)) { |
|
91 |
+ msg (M_FATAL, "PKCS#11: mbed TLS cannot parse subject"); |
|
92 |
+ goto cleanup; |
|
93 |
+ } |
|
94 |
+ |
|
95 |
+ ret = string_alloc(dn, gc); |
|
96 |
+ |
|
97 |
+cleanup: |
|
98 |
+ mbedtls_x509_crt_free(&mbed_crt); |
|
99 |
+ |
|
100 |
+ return ret; |
|
101 |
+} |
|
102 |
+ |
|
103 |
+int |
|
104 |
+pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial, |
|
105 |
+ size_t serial_len) |
|
106 |
+{ |
|
107 |
+ int ret = 1; |
|
108 |
+ |
|
109 |
+ mbedtls_x509_crt mbed_crt = {0}; |
|
110 |
+ |
|
111 |
+ if (mbedtls_pkcs11_x509_cert_bind(&mbed_crt, cert)) { |
|
112 |
+ msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object"); |
|
113 |
+ goto cleanup; |
|
114 |
+ } |
|
115 |
+ |
|
116 |
+ if (-1 == mbedtls_x509_serial_gets (serial, serial_len, &mbed_crt.serial)) { |
|
117 |
+ msg (M_FATAL, "PKCS#11: mbed TLS cannot parse serial"); |
|
118 |
+ goto cleanup; |
|
119 |
+ } |
|
120 |
+ |
|
121 |
+ ret = 0; |
|
122 |
+ |
|
123 |
+cleanup: |
|
124 |
+ mbedtls_x509_crt_free(&mbed_crt); |
|
125 |
+ |
|
126 |
+ return ret; |
|
127 |
+} |
|
128 |
+#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) */ |
0 | 129 |
deleted file mode 100644 |
... | ... |
@@ -1,129 +0,0 @@ |
1 |
-/* |
|
2 |
- * OpenVPN -- An application to securely tunnel IP networks |
|
3 |
- * over a single TCP/UDP port, with support for SSL/TLS-based |
|
4 |
- * session authentication and key exchange, |
|
5 |
- * packet encryption, packet authentication, and |
|
6 |
- * packet compression. |
|
7 |
- * |
|
8 |
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
9 |
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
10 |
- * |
|
11 |
- * This program is free software; you can redistribute it and/or modify |
|
12 |
- * it under the terms of the GNU General Public License version 2 |
|
13 |
- * as published by the Free Software Foundation. |
|
14 |
- * |
|
15 |
- * This program is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
- * GNU General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU General Public License |
|
21 |
- * along with this program (see the file COPYING included with this |
|
22 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
23 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
- */ |
|
25 |
- |
|
26 |
-/** |
|
27 |
- * @file PKCS #11 mbed TLS backend |
|
28 |
- */ |
|
29 |
- |
|
30 |
-#ifdef HAVE_CONFIG_H |
|
31 |
-#include "config.h" |
|
32 |
-#elif defined(_MSC_VER) |
|
33 |
-#include "config-msvc.h" |
|
34 |
-#endif |
|
35 |
- |
|
36 |
-#include "syshead.h" |
|
37 |
- |
|
38 |
-#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
39 |
- |
|
40 |
-#include "errlevel.h" |
|
41 |
-#include "pkcs11_backend.h" |
|
42 |
-#include <mbedtls/pkcs11.h> |
|
43 |
-#include <mbedtls/x509.h> |
|
44 |
- |
|
45 |
-int |
|
46 |
-pkcs11_init_tls_session(pkcs11h_certificate_t certificate, |
|
47 |
- struct tls_root_ctx * const ssl_ctx) |
|
48 |
-{ |
|
49 |
- int ret = 1; |
|
50 |
- |
|
51 |
- ASSERT (NULL != ssl_ctx); |
|
52 |
- |
|
53 |
- ALLOC_OBJ_CLEAR (ssl_ctx->crt_chain, mbedtls_x509_crt); |
|
54 |
- if (mbedtls_pkcs11_x509_cert_bind(ssl_ctx->crt_chain, certificate)) { |
|
55 |
- msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object"); |
|
56 |
- goto cleanup; |
|
57 |
- } |
|
58 |
- |
|
59 |
- ALLOC_OBJ_CLEAR (ssl_ctx->priv_key_pkcs11, mbedtls_pkcs11_context); |
|
60 |
- if (mbedtls_pkcs11_priv_key_bind(ssl_ctx->priv_key_pkcs11, certificate)) { |
|
61 |
- msg (M_FATAL, "PKCS#11: Cannot initialize mbed TLS private key object"); |
|
62 |
- goto cleanup; |
|
63 |
- } |
|
64 |
- |
|
65 |
- ALLOC_OBJ_CLEAR (ssl_ctx->priv_key, mbedtls_pk_context); |
|
66 |
- if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ssl_ctx->priv_key, |
|
67 |
- ssl_ctx->priv_key_pkcs11, mbedtls_ssl_pkcs11_decrypt, |
|
68 |
- mbedtls_ssl_pkcs11_sign, mbedtls_ssl_pkcs11_key_len))) { |
|
69 |
- goto cleanup; |
|
70 |
- } |
|
71 |
- |
|
72 |
- ret = 0; |
|
73 |
- |
|
74 |
-cleanup: |
|
75 |
- return ret; |
|
76 |
-} |
|
77 |
- |
|
78 |
-char * |
|
79 |
-pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc) |
|
80 |
-{ |
|
81 |
- char *ret = NULL; |
|
82 |
- char dn[1024] = {0}; |
|
83 |
- |
|
84 |
- mbedtls_x509_crt mbed_crt = {0}; |
|
85 |
- |
|
86 |
- if (mbedtls_pkcs11_x509_cert_bind(&mbed_crt, cert)) { |
|
87 |
- msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object"); |
|
88 |
- goto cleanup; |
|
89 |
- } |
|
90 |
- |
|
91 |
- if (-1 == mbedtls_x509_dn_gets (dn, sizeof(dn), &mbed_crt.subject)) { |
|
92 |
- msg (M_FATAL, "PKCS#11: mbed TLS cannot parse subject"); |
|
93 |
- goto cleanup; |
|
94 |
- } |
|
95 |
- |
|
96 |
- ret = string_alloc(dn, gc); |
|
97 |
- |
|
98 |
-cleanup: |
|
99 |
- mbedtls_x509_crt_free(&mbed_crt); |
|
100 |
- |
|
101 |
- return ret; |
|
102 |
-} |
|
103 |
- |
|
104 |
-int |
|
105 |
-pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial, |
|
106 |
- size_t serial_len) |
|
107 |
-{ |
|
108 |
- int ret = 1; |
|
109 |
- |
|
110 |
- mbedtls_x509_crt mbed_crt = {0}; |
|
111 |
- |
|
112 |
- if (mbedtls_pkcs11_x509_cert_bind(&mbed_crt, cert)) { |
|
113 |
- msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object"); |
|
114 |
- goto cleanup; |
|
115 |
- } |
|
116 |
- |
|
117 |
- if (-1 == mbedtls_x509_serial_gets (serial, serial_len, &mbed_crt.serial)) { |
|
118 |
- msg (M_FATAL, "PKCS#11: mbed TLS cannot parse serial"); |
|
119 |
- goto cleanup; |
|
120 |
- } |
|
121 |
- |
|
122 |
- ret = 0; |
|
123 |
- |
|
124 |
-cleanup: |
|
125 |
- mbedtls_x509_crt_free(&mbed_crt); |
|
126 |
- |
|
127 |
- return ret; |
|
128 |
-} |
|
129 |
-#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) */ |
47 | 47 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,1184 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
9 |
+ * Copyright (C) 2006-2010, Brainspark B.V. |
|
10 |
+ * |
|
11 |
+ * This program is free software; you can redistribute it and/or modify |
|
12 |
+ * it under the terms of the GNU General Public License version 2 |
|
13 |
+ * as published by the Free Software Foundation. |
|
14 |
+ * |
|
15 |
+ * This program is distributed in the hope that it will be useful, |
|
16 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
+ * GNU General Public License for more details. |
|
19 |
+ * |
|
20 |
+ * You should have received a copy of the GNU General Public License |
|
21 |
+ * along with this program (see the file COPYING included with this |
|
22 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
23 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
+ */ |
|
25 |
+ |
|
26 |
+/** |
|
27 |
+ * @file Control Channel mbed TLS Backend |
|
28 |
+ */ |
|
29 |
+ |
|
30 |
+#ifdef HAVE_CONFIG_H |
|
31 |
+#include "config.h" |
|
32 |
+#elif defined(_MSC_VER) |
|
33 |
+#include "config-msvc.h" |
|
34 |
+#endif |
|
35 |
+ |
|
36 |
+#include "syshead.h" |
|
37 |
+ |
|
38 |
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
39 |
+ |
|
40 |
+#include "errlevel.h" |
|
41 |
+#include "ssl_backend.h" |
|
42 |
+#include "base64.h" |
|
43 |
+#include "buffer.h" |
|
44 |
+#include "misc.h" |
|
45 |
+#include "manage.h" |
|
46 |
+#include "ssl_common.h" |
|
47 |
+ |
|
48 |
+#include <mbedtls/havege.h> |
|
49 |
+ |
|
50 |
+#include "ssl_verify_mbedtls.h" |
|
51 |
+#include <mbedtls/debug.h> |
|
52 |
+#include <mbedtls/error.h> |
|
53 |
+#include <mbedtls/net.h> |
|
54 |
+#include <mbedtls/oid.h> |
|
55 |
+#include <mbedtls/pem.h> |
|
56 |
+#include <mbedtls/sha256.h> |
|
57 |
+#include <mbedtls/version.h> |
|
58 |
+ |
|
59 |
+void |
|
60 |
+tls_init_lib() |
|
61 |
+{ |
|
62 |
+} |
|
63 |
+ |
|
64 |
+void |
|
65 |
+tls_free_lib() |
|
66 |
+{ |
|
67 |
+} |
|
68 |
+ |
|
69 |
+void |
|
70 |
+tls_clear_error() |
|
71 |
+{ |
|
72 |
+} |
|
73 |
+ |
|
74 |
+void |
|
75 |
+tls_ctx_server_new(struct tls_root_ctx *ctx) |
|
76 |
+{ |
|
77 |
+ ASSERT(NULL != ctx); |
|
78 |
+ CLEAR(*ctx); |
|
79 |
+ |
|
80 |
+ ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context); |
|
81 |
+ |
|
82 |
+ ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt); |
|
83 |
+ |
|
84 |
+ ctx->endpoint = MBEDTLS_SSL_IS_SERVER; |
|
85 |
+ ctx->initialised = true; |
|
86 |
+} |
|
87 |
+ |
|
88 |
+void |
|
89 |
+tls_ctx_client_new(struct tls_root_ctx *ctx) |
|
90 |
+{ |
|
91 |
+ ASSERT(NULL != ctx); |
|
92 |
+ CLEAR(*ctx); |
|
93 |
+ |
|
94 |
+ ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context); |
|
95 |
+ ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt); |
|
96 |
+ |
|
97 |
+ ctx->endpoint = MBEDTLS_SSL_IS_CLIENT; |
|
98 |
+ ctx->initialised = true; |
|
99 |
+} |
|
100 |
+ |
|
101 |
+void |
|
102 |
+tls_ctx_free(struct tls_root_ctx *ctx) |
|
103 |
+{ |
|
104 |
+ if (ctx) |
|
105 |
+ { |
|
106 |
+ mbedtls_pk_free(ctx->priv_key); |
|
107 |
+ if (ctx->priv_key) |
|
108 |
+ free(ctx->priv_key); |
|
109 |
+ |
|
110 |
+ mbedtls_x509_crt_free(ctx->ca_chain); |
|
111 |
+ if (ctx->ca_chain) |
|
112 |
+ free(ctx->ca_chain); |
|
113 |
+ |
|
114 |
+ mbedtls_x509_crt_free(ctx->crt_chain); |
|
115 |
+ if (ctx->crt_chain) |
|
116 |
+ free(ctx->crt_chain); |
|
117 |
+ |
|
118 |
+ mbedtls_dhm_free(ctx->dhm_ctx); |
|
119 |
+ if (ctx->dhm_ctx) |
|
120 |
+ free(ctx->dhm_ctx); |
|
121 |
+ |
|
122 |
+#if defined(ENABLE_PKCS11) |
|
123 |
+ if (ctx->priv_key_pkcs11 != NULL) { |
|
124 |
+ mbedtls_pkcs11_priv_key_free(ctx->priv_key_pkcs11); |
|
125 |
+ free(ctx->priv_key_pkcs11); |
|
126 |
+ } |
|
127 |
+#endif |
|
128 |
+#if defined(MANAGMENT_EXTERNAL_KEY) |
|
129 |
+ if (ctx->external_key != NULL) |
|
130 |
+ free(ctx->external_key); |
|
131 |
+#endif |
|
132 |
+ |
|
133 |
+ if (ctx->allowed_ciphers) |
|
134 |
+ free(ctx->allowed_ciphers); |
|
135 |
+ |
|
136 |
+ CLEAR(*ctx); |
|
137 |
+ |
|
138 |
+ ctx->initialised = false; |
|
139 |
+ |
|
140 |
+ } |
|
141 |
+} |
|
142 |
+ |
|
143 |
+bool |
|
144 |
+tls_ctx_initialised(struct tls_root_ctx *ctx) |
|
145 |
+{ |
|
146 |
+ ASSERT(NULL != ctx); |
|
147 |
+ return ctx->initialised; |
|
148 |
+} |
|
149 |
+ |
|
150 |
+void |
|
151 |
+key_state_export_keying_material(struct key_state_ssl *ssl, |
|
152 |
+ struct tls_session *session) |
|
153 |
+{ |
|
154 |
+} |
|
155 |
+ |
|
156 |
+void |
|
157 |
+tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) |
|
158 |
+{ |
|
159 |
+} |
|
160 |
+ |
|
161 |
+static const char * |
|
162 |
+tls_translate_cipher_name (const char * cipher_name) { |
|
163 |
+ const tls_cipher_name_pair * pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name)); |
|
164 |
+ |
|
165 |
+ if (NULL == pair) |
|
166 |
+ { |
|
167 |
+ // No translation found, return original |
|
168 |
+ return cipher_name; |
|
169 |
+ } |
|
170 |
+ |
|
171 |
+ if (0 != strcmp(cipher_name, pair->iana_name)) |
|
172 |
+ { |
|
173 |
+ // Deprecated name found, notify user |
|
174 |
+ msg(M_WARN, "Deprecated cipher suite name '%s', please use IANA name '%s'", pair->openssl_name, pair->iana_name); |
|
175 |
+ } |
|
176 |
+ |
|
177 |
+ return pair->iana_name; |
|
178 |
+} |
|
179 |
+ |
|
180 |
+void |
|
181 |
+tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) |
|
182 |
+{ |
|
183 |
+ char *tmp_ciphers, *tmp_ciphers_orig, *token; |
|
184 |
+ int i, cipher_count; |
|
185 |
+ int ciphers_len; |
|
186 |
+ |
|
187 |
+ if (NULL == ciphers) |
|
188 |
+ return; /* Nothing to do */ |
|
189 |
+ |
|
190 |
+ ciphers_len = strlen (ciphers); |
|
191 |
+ |
|
192 |
+ ASSERT (NULL != ctx); |
|
193 |
+ ASSERT (0 != ciphers_len); |
|
194 |
+ |
|
195 |
+ /* Get number of ciphers */ |
|
196 |
+ for (i = 0, cipher_count = 1; i < ciphers_len; i++) |
|
197 |
+ if (ciphers[i] == ':') |
|
198 |
+ cipher_count++; |
|
199 |
+ |
|
200 |
+ /* Allocate an array for them */ |
|
201 |
+ ALLOC_ARRAY_CLEAR(ctx->allowed_ciphers, int, cipher_count+1) |
|
202 |
+ |
|
203 |
+ /* Parse allowed ciphers, getting IDs */ |
|
204 |
+ i = 0; |
|
205 |
+ tmp_ciphers_orig = tmp_ciphers = string_alloc (ciphers, NULL); |
|
206 |
+ |
|
207 |
+ token = strtok (tmp_ciphers, ":"); |
|
208 |
+ while(token) |
|
209 |
+ { |
|
210 |
+ ctx->allowed_ciphers[i] = mbedtls_ssl_get_ciphersuite_id ( |
|
211 |
+ tls_translate_cipher_name (token)); |
|
212 |
+ if (0 != ctx->allowed_ciphers[i]) |
|
213 |
+ i++; |
|
214 |
+ token = strtok (NULL, ":"); |
|
215 |
+ } |
|
216 |
+ free(tmp_ciphers_orig); |
|
217 |
+} |
|
218 |
+ |
|
219 |
+void |
|
220 |
+tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) |
|
221 |
+{ |
|
222 |
+ ASSERT (ctx); |
|
223 |
+ if (ctx->crt_chain == NULL) |
|
224 |
+ { |
|
225 |
+ return; /* Nothing to check if there is no certificate */ |
|
226 |
+ } |
|
227 |
+ |
|
228 |
+ if (mbedtls_x509_time_is_future (&ctx->crt_chain->valid_from)) |
|
229 |
+ { |
|
230 |
+ msg (M_WARN, "WARNING: Your certificate is not yet valid!"); |
|
231 |
+ } |
|
232 |
+ |
|
233 |
+ if (mbedtls_x509_time_is_past (&ctx->crt_chain->valid_to)) |
|
234 |
+ { |
|
235 |
+ msg (M_WARN, "WARNING: Your certificate has expired!"); |
|
236 |
+ } |
|
237 |
+} |
|
238 |
+ |
|
239 |
+void |
|
240 |
+tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, |
|
241 |
+ const char *dh_inline |
|
242 |
+ ) |
|
243 |
+{ |
|
244 |
+ if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline) |
|
245 |
+ { |
|
246 |
+ if (!mbed_ok(mbedtls_dhm_parse_dhm(ctx->dhm_ctx, |
|
247 |
+ (const unsigned char *) dh_inline, strlen(dh_inline)+1))) |
|
248 |
+ msg (M_FATAL, "Cannot read inline DH parameters"); |
|
249 |
+ } |
|
250 |
+else |
|
251 |
+ { |
|
252 |
+ if (!mbed_ok(mbedtls_dhm_parse_dhmfile(ctx->dhm_ctx, dh_file))) |
|
253 |
+ msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file); |
|
254 |
+ } |
|
255 |
+ |
|
256 |
+ msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with " counter_format " bit key", |
|
257 |
+ (counter_type) 8 * mbedtls_mpi_size(&ctx->dhm_ctx->P)); |
|
258 |
+} |
|
259 |
+ |
|
260 |
+void |
|
261 |
+tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name |
|
262 |
+ ) |
|
263 |
+{ |
|
264 |
+ if (NULL != curve_name) |
|
265 |
+ msg(M_WARN, "WARNING: mbed TLS builds do not support specifying an ECDH " |
|
266 |
+ "curve, using default curves."); |
|
267 |
+} |
|
268 |
+ |
|
269 |
+int |
|
270 |
+tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, |
|
271 |
+ const char *pkcs12_file_inline, |
|
272 |
+ bool load_ca_file |
|
273 |
+ ) |
|
274 |
+{ |
|
275 |
+ msg(M_FATAL, "PKCS #12 files not yet supported for mbed TLS."); |
|
276 |
+ return 0; |
|
277 |
+} |
|
278 |
+ |
|
279 |
+#ifdef ENABLE_CRYPTOAPI |
|
280 |
+void |
|
281 |
+tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert) |
|
282 |
+{ |
|
283 |
+ msg(M_FATAL, "Windows CryptoAPI not yet supported for mbed TLS."); |
|
284 |
+} |
|
285 |
+#endif /* WIN32 */ |
|
286 |
+ |
|
287 |
+void |
|
288 |
+tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, |
|
289 |
+ const char *cert_inline |
|
290 |
+ ) |
|
291 |
+{ |
|
292 |
+ ASSERT(NULL != ctx); |
|
293 |
+ |
|
294 |
+ if (!ctx->crt_chain) |
|
295 |
+ { |
|
296 |
+ ALLOC_OBJ_CLEAR(ctx->crt_chain, mbedtls_x509_crt); |
|
297 |
+ } |
|
298 |
+ |
|
299 |
+ if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline) |
|
300 |
+ { |
|
301 |
+ if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain, |
|
302 |
+ (const unsigned char *) cert_inline, strlen(cert_inline)+1))) |
|
303 |
+ msg (M_FATAL, "Cannot load inline certificate file"); |
|
304 |
+ } |
|
305 |
+ else |
|
306 |
+ { |
|
307 |
+ if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, cert_file))) |
|
308 |
+ { |
|
309 |
+ msg (M_FATAL, "Cannot load certificate file %s", cert_file); |
|
310 |
+ } |
|
311 |
+ } |
|
312 |
+} |
|
313 |
+ |
|
314 |
+int |
|
315 |
+tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, |
|
316 |
+ const char *priv_key_inline |
|
317 |
+ ) |
|
318 |
+{ |
|
319 |
+ int status; |
|
320 |
+ ASSERT(NULL != ctx); |
|
321 |
+ |
|
322 |
+ if (!ctx->priv_key) |
|
323 |
+ { |
|
324 |
+ ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context); |
|
325 |
+ } |
|
326 |
+ |
|
327 |
+ if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_inline) |
|
328 |
+ { |
|
329 |
+ status = mbedtls_pk_parse_key(ctx->priv_key, |
|
330 |
+ (const unsigned char *) priv_key_inline, strlen(priv_key_inline)+1, |
|
331 |
+ NULL, 0); |
|
332 |
+ |
|
333 |
+ if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status) |
|
334 |
+ { |
|
335 |
+ char passbuf[512] = {0}; |
|
336 |
+ pem_password_callback(passbuf, 512, 0, NULL); |
|
337 |
+ status = mbedtls_pk_parse_key(ctx->priv_key, |
|
338 |
+ (const unsigned char *) priv_key_inline, |
|
339 |
+ strlen(priv_key_inline)+1, (unsigned char *) passbuf, |
|
340 |
+ strlen(passbuf)); |
|
341 |
+ } |
|
342 |
+ } |
|
343 |
+ else |
|
344 |
+ { |
|
345 |
+ status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL); |
|
346 |
+ if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status) |
|
347 |
+ { |
|
348 |
+ char passbuf[512] = {0}; |
|
349 |
+ pem_password_callback(passbuf, 512, 0, NULL); |
|
350 |
+ status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf); |
|
351 |
+ } |
|
352 |
+ } |
|
353 |
+ if (!mbed_ok(status)) |
|
354 |
+ { |
|
355 |
+#ifdef ENABLE_MANAGEMENT |
|
356 |
+ if (management && (MBEDTLS_ERR_PK_PASSWORD_MISMATCH == status)) |
|
357 |
+ management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); |
|
358 |
+#endif |
|
359 |
+ msg (M_WARN, "Cannot load private key file %s", priv_key_file); |
|
360 |
+ return 1; |
|
361 |
+ } |
|
362 |
+ |
|
363 |
+ warn_if_group_others_accessible (priv_key_file); |
|
364 |
+ |
|
365 |
+ /* TODO: Check Private Key */ |
|
366 |
+#if 0 |
|
367 |
+ if (!SSL_CTX_check_private_key (ctx)) |
|
368 |
+ msg (M_SSLERR, "Private key does not match the certificate"); |
|
369 |
+#endif |
|
370 |
+ return 0; |
|
371 |
+} |
|
372 |
+ |
|
373 |
+#ifdef MANAGMENT_EXTERNAL_KEY |
|
374 |
+ |
|
375 |
+ |
|
376 |
+struct external_context { |
|
377 |
+ size_t signature_length; |
|
378 |
+}; |
|
379 |
+ |
|
380 |
+/** |
|
381 |
+ * external_pkcs1_sign implements a mbed TLS rsa_sign_func callback, that uses |
|
382 |
+ * the management interface to request an RSA signature for the supplied hash. |
|
383 |
+ * |
|
384 |
+ * @param ctx_voidptr Management external key context. |
|
385 |
+ * @param f_rng (Unused) |
|
386 |
+ * @param p_rng (Unused) |
|
387 |
+ * @param mode RSA mode (should be RSA_PRIVATE). |
|
388 |
+ * @param md_alg Message digest ('hash') algorithm type. |
|
389 |
+ * @param hashlen Length of hash (overridden by length specified by md_alg |
|
390 |
+ * if md_alg != MBEDTLS_MD_NONE). |
|
391 |
+ * @param hash The digest ('hash') to sign. Should have a size |
|
392 |
+ * matching the length of md_alg (if != MBEDTLS_MD_NONE), |
|
393 |
+ * or hashlen otherwise. |
|
394 |
+ * @param sig Buffer that returns the signature. Should be at least of |
|
395 |
+ * size ctx->signature_length. |
|
396 |
+ * |
|
397 |
+ * @return 0 on success, non-zero mbed TLS error code on failure. |
|
398 |
+ */ |
|
399 |
+static inline int external_pkcs1_sign( void *ctx_voidptr, |
|
400 |
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, |
|
401 |
+ mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, |
|
402 |
+ unsigned char *sig ) |
|
403 |
+{ |
|
404 |
+ struct external_context * const ctx = ctx_voidptr; |
|
405 |
+ char *in_b64 = NULL; |
|
406 |
+ char *out_b64 = NULL; |
|
407 |
+ int rv; |
|
408 |
+ unsigned char *p = sig; |
|
409 |
+ size_t asn_len = 0, oid_size = 0, sig_len = 0; |
|
410 |
+ const char *oid = NULL; |
|
411 |
+ |
|
412 |
+ if( NULL == ctx ) |
|
413 |
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
414 |
+ |
|
415 |
+ if( MBEDTLS_RSA_PRIVATE != mode ) |
|
416 |
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
417 |
+ |
|
418 |
+ /* |
|
419 |
+ * Support a wide range of hashes. TLSv1.1 and before only need SIG_RSA_RAW, |
|
420 |
+ * but TLSv1.2 needs the full suite of hashes. |
|
421 |
+ * |
|
422 |
+ * This code has been taken from mbed TLS pkcs11_sign(), under the GPLv2.0+. |
|
423 |
+ */ |
|
424 |
+ if( md_alg != MBEDTLS_MD_NONE ) |
|
425 |
+ { |
|
426 |
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); |
|
427 |
+ if( md_info == NULL ) |
|
428 |
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
|
429 |
+ |
|
430 |
+ if (!mbed_ok(mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ))) |
|
431 |
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
|
432 |
+ |
|
433 |
+ hashlen = mbedtls_md_get_size( md_info ); |
|
434 |
+ asn_len = 10 + oid_size; |
|
435 |
+ } |
|
436 |
+ |
|
437 |
+ sig_len = ctx->signature_length; |
|
438 |
+ if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len ) |
|
439 |
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
440 |
+ |
|
441 |
+ if( md_alg != MBEDTLS_MD_NONE ) |
|
442 |
+ { |
|
443 |
+ /* |
|
444 |
+ * DigestInfo ::= SEQUENCE { |
|
445 |
+ * digestAlgorithm DigestAlgorithmIdentifier, |
|
446 |
+ * digest Digest } |
|
447 |
+ * |
|
448 |
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier |
|
449 |
+ * |
|
450 |
+ * Digest ::= OCTET STRING |
|
451 |
+ */ |
|
452 |
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
|
453 |
+ *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); |
|
454 |
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
|
455 |
+ *p++ = (unsigned char) ( 0x04 + oid_size ); |
|
456 |
+ *p++ = MBEDTLS_ASN1_OID; |
|
457 |
+ *p++ = oid_size & 0xFF; |
|
458 |
+ memcpy( p, oid, oid_size ); |
|
459 |
+ p += oid_size; |
|
460 |
+ *p++ = MBEDTLS_ASN1_NULL; |
|
461 |
+ *p++ = 0x00; |
|
462 |
+ *p++ = MBEDTLS_ASN1_OCTET_STRING; |
|
463 |
+ *p++ = hashlen; |
|
464 |
+ |
|
465 |
+ /* Determine added ASN length */ |
|
466 |
+ asn_len = p - sig; |
|
467 |
+ } |
|
468 |
+ |
|
469 |
+ /* Copy the hash to be signed */ |
|
470 |
+ memcpy( p, hash, hashlen ); |
|
471 |
+ |
|
472 |
+ /* convert 'from' to base64 */ |
|
473 |
+ if (openvpn_base64_encode (sig, asn_len + hashlen, &in_b64) <= 0) |
|
474 |
+ { |
|
475 |
+ rv = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
476 |
+ goto done; |
|
477 |
+ } |
|
478 |
+ |
|
479 |
+ /* call MI for signature */ |
|
480 |
+ if (management) |
|
481 |
+ out_b64 = management_query_rsa_sig (management, in_b64); |
|
482 |
+ if (!out_b64) |
|
483 |
+ { |
|
484 |
+ rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; |
|
485 |
+ goto done; |
|
486 |
+ } |
|
487 |
+ |
|
488 |
+ /* decode base64 signature to binary and verify length */ |
|
489 |
+ if ( openvpn_base64_decode (out_b64, sig, ctx->signature_length) != |
|
490 |
+ ctx->signature_length ) |
|
491 |
+ { |
|
492 |
+ rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; |
|
493 |
+ goto done; |
|
494 |
+ } |
|
495 |
+ |
|
496 |
+ rv = 0; |
|
497 |
+ |
|
498 |
+done: |
|
499 |
+ if (in_b64) |
|
500 |
+ free (in_b64); |
|
501 |
+ if (out_b64) |
|
502 |
+ free (out_b64); |
|
503 |
+ return rv; |
|
504 |
+} |
|
505 |
+ |
|
506 |
+static inline size_t external_key_len(void *vctx) |
|
507 |
+{ |
|
508 |
+ struct external_context * const ctx = vctx; |
|
509 |
+ |
|
510 |
+ return ctx->signature_length; |
|
511 |
+} |
|
512 |
+ |
|
513 |
+int |
|
514 |
+tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, |
|
515 |
+ const char *cert_file, const char *cert_file_inline) |
|
516 |
+{ |
|
517 |
+ ASSERT(NULL != ctx); |
|
518 |
+ |
|
519 |
+ tls_ctx_load_cert_file(ctx, cert_file, cert_file_inline); |
|
520 |
+ |
|
521 |
+ if (ctx->crt_chain == NULL) |
|
522 |
+ return 0; |
|
523 |
+ |
|
524 |
+ ALLOC_OBJ_CLEAR (ctx->external_key, struct external_context); |
|
525 |
+ ctx->external_key->signature_length = mbedtls_pk_get_len (&ctx->crt_chain->pk); |
|
526 |
+ |
|
527 |
+ ALLOC_OBJ_CLEAR (ctx->priv_key, mbedtls_pk_context); |
|
528 |
+ if (!mbed_ok (mbedtls_pk_setup_rsa_alt (ctx->priv_key, ctx->external_key, |
|
529 |
+ NULL, external_pkcs1_sign, external_key_len))) |
|
530 |
+ return 0; |
|
531 |
+ |
|
532 |
+ return 1; |
|
533 |
+} |
|
534 |
+#endif |
|
535 |
+ |
|
536 |
+void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, |
|
537 |
+ const char *ca_inline, const char *ca_path, bool tls_server |
|
538 |
+ ) |
|
539 |
+{ |
|
540 |
+ if (ca_path) |
|
541 |
+ msg(M_FATAL, "ERROR: mbed TLS cannot handle the capath directive"); |
|
542 |
+ |
|
543 |
+ if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline) |
|
544 |
+ { |
|
545 |
+ if (!mbed_ok (mbedtls_x509_crt_parse (ctx->ca_chain, |
|
546 |
+ (const unsigned char *) ca_inline, strlen(ca_inline)+1))) |
|
547 |
+ msg (M_FATAL, "Cannot load inline CA certificates"); |
|
548 |
+ } |
|
549 |
+ else |
|
550 |
+ { |
|
551 |
+ /* Load CA file for verifying peer supplied certificate */ |
|
552 |
+ if (!mbed_ok (mbedtls_x509_crt_parse_file (ctx->ca_chain, ca_file))) |
|
553 |
+ msg (M_FATAL, "Cannot load CA certificate file %s", ca_file); |
|
554 |
+ } |
|
555 |
+} |
|
556 |
+ |
|
557 |
+void |
|
558 |
+tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file, |
|
559 |
+ const char *extra_certs_inline |
|
560 |
+ ) |
|
561 |
+{ |
|
562 |
+ ASSERT(NULL != ctx); |
|
563 |
+ |
|
564 |
+ if (!ctx->crt_chain) |
|
565 |
+ { |
|
566 |
+ ALLOC_OBJ_CLEAR (ctx->crt_chain, mbedtls_x509_crt); |
|
567 |
+ } |
|
568 |
+ |
|
569 |
+ if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline) |
|
570 |
+ { |
|
571 |
+ if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain, |
|
572 |
+ (const unsigned char *) extra_certs_inline, |
|
573 |
+ strlen(extra_certs_inline)+1))) |
|
574 |
+ msg (M_FATAL, "Cannot load inline extra-certs file"); |
|
575 |
+ } |
|
576 |
+ else |
|
577 |
+ { |
|
578 |
+ if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, extra_certs_file))) |
|
579 |
+ msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file); |
|
580 |
+ } |
|
581 |
+} |
|
582 |
+ |
|
583 |
+/* ************************************** |
|
584 |
+ * |
|
585 |
+ * Key-state specific functions |
|
586 |
+ * |
|
587 |
+ ***************************************/ |
|
588 |
+ |
|
589 |
+/* |
|
590 |
+ * "Endless buffer" |
|
591 |
+ */ |
|
592 |
+ |
|
593 |
+static inline void buf_free_entry(buffer_entry *entry) |
|
594 |
+{ |
|
595 |
+ if (NULL != entry) |
|
596 |
+ { |
|
597 |
+ free(entry->data); |
|
598 |
+ free(entry); |
|
599 |
+ } |
|
600 |
+} |
|
601 |
+ |
|
602 |
+static void buf_free_entries(endless_buffer *buf) |
|
603 |
+{ |
|
604 |
+ while(buf->first_block) |
|
605 |
+ { |
|
606 |
+ buffer_entry *cur_block = buf->first_block; |
|
607 |
+ buf->first_block = cur_block->next_block; |
|
608 |
+ buf_free_entry(cur_block); |
|
609 |
+ } |
|
610 |
+ buf->last_block = NULL; |
|
611 |
+} |
|
612 |
+ |
|
613 |
+static int endless_buf_read( endless_buffer *in, unsigned char * out, size_t out_len ) |
|
614 |
+{ |
|
615 |
+ size_t read_len = 0; |
|
616 |
+ |
|
617 |
+ if (in->first_block == NULL) |
|
618 |
+ return MBEDTLS_ERR_SSL_WANT_READ; |
|
619 |
+ |
|
620 |
+ while (in->first_block != NULL && read_len < out_len) |
|
621 |
+ { |
|
622 |
+ int block_len = in->first_block->length - in->data_start; |
|
623 |
+ if (block_len <= out_len - read_len) |
|
624 |
+ { |
|
625 |
+ buffer_entry *cur_entry = in->first_block; |
|
626 |
+ memcpy(out + read_len, cur_entry->data + in->data_start, |
|
627 |
+ block_len); |
|
628 |
+ |
|
629 |
+ read_len += block_len; |
|
630 |
+ |
|
631 |
+ in->first_block = cur_entry->next_block; |
|
632 |
+ in->data_start = 0; |
|
633 |
+ |
|
634 |
+ if (in->first_block == NULL) |
|
635 |
+ in->last_block = NULL; |
|
636 |
+ |
|
637 |
+ buf_free_entry(cur_entry); |
|
638 |
+ } |
|
639 |
+ else |
|
640 |
+ { |
|
641 |
+ memcpy(out + read_len, in->first_block->data + in->data_start, |
|
642 |
+ out_len - read_len); |
|
643 |
+ in->data_start += out_len - read_len; |
|
644 |
+ read_len = out_len; |
|
645 |
+ } |
|
646 |
+ } |
|
647 |
+ |
|
648 |
+ return read_len; |
|
649 |
+} |
|
650 |
+ |
|
651 |
+static int endless_buf_write( endless_buffer *out, const unsigned char *in, size_t len ) |
|
652 |
+{ |
|
653 |
+ buffer_entry *new_block = malloc(sizeof(buffer_entry)); |
|
654 |
+ if (NULL == new_block) |
|
655 |
+ return MBEDTLS_ERR_NET_SEND_FAILED; |
|
656 |
+ |
|
657 |
+ new_block->data = malloc(len); |
|
658 |
+ if (NULL == new_block->data) |
|
659 |
+ { |
|
660 |
+ free(new_block); |
|
661 |
+ return MBEDTLS_ERR_NET_SEND_FAILED; |
|
662 |
+ } |
|
663 |
+ |
|
664 |
+ new_block->length = len; |
|
665 |
+ new_block->next_block = NULL; |
|
666 |
+ |
|
667 |
+ memcpy(new_block->data, in, len); |
|
668 |
+ |
|
669 |
+ if (NULL == out->first_block) |
|
670 |
+ out->first_block = new_block; |
|
671 |
+ |
|
672 |
+ if (NULL != out->last_block) |
|
673 |
+ out->last_block->next_block = new_block; |
|
674 |
+ |
|
675 |
+ out->last_block = new_block; |
|
676 |
+ |
|
677 |
+ return len; |
|
678 |
+} |
|
679 |
+ |
|
680 |
+static int ssl_bio_read( void *ctx, unsigned char *out, size_t out_len) |
|
681 |
+{ |
|
682 |
+ bio_ctx *my_ctx = (bio_ctx *) ctx; |
|
683 |
+ return endless_buf_read (&my_ctx->in, out, out_len); |
|
684 |
+} |
|
685 |
+ |
|
686 |
+static int ssl_bio_write( void *ctx, const unsigned char *in, size_t in_len) |
|
687 |
+{ |
|
688 |
+ bio_ctx *my_ctx = (bio_ctx *) ctx; |
|
689 |
+ return endless_buf_write (&my_ctx->out, in, in_len); |
|
690 |
+} |
|
691 |
+ |
|
692 |
+static void my_debug( void *ctx, int level, const char *file, int line, |
|
693 |
+ const char *str ) |
|
694 |
+{ |
|
695 |
+ int my_loglevel = (level < 3) ? D_TLS_DEBUG_MED : D_TLS_DEBUG; |
|
696 |
+ msg (my_loglevel, "mbed TLS msg (%s:%d): %s", file, line, str); |
|
697 |
+} |
|
698 |
+ |
|
699 |
+/* |
|
700 |
+ * Further personalise the RNG using a hash of the public key |
|
701 |
+ */ |
|
702 |
+void tls_ctx_personalise_random(struct tls_root_ctx *ctx) |
|
703 |
+{ |
|
704 |
+ static char old_sha256_hash[32] = {0}; |
|
705 |
+ unsigned char sha256_hash[32] = {0}; |
|
706 |
+ mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get(); |
|
707 |
+ |
|
708 |
+ if (NULL != ctx->crt_chain) |
|
709 |
+ { |
|
710 |
+ mbedtls_x509_crt *cert = ctx->crt_chain; |
|
711 |
+ |
|
712 |
+ mbedtls_sha256(cert->tbs.p, cert->tbs.len, sha256_hash, false); |
|
713 |
+ if ( 0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash))) |
|
714 |
+ { |
|
715 |
+ mbedtls_ctr_drbg_update(cd_ctx, sha256_hash, 32); |
|
716 |
+ memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash)); |
|
717 |
+ } |
|
718 |
+ } |
|
719 |
+} |
|
720 |
+ |
|
721 |
+int |
|
722 |
+tls_version_max(void) |
|
723 |
+{ |
|
724 |
+#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_3) |
|
725 |
+ return TLS_VER_1_2; |
|
726 |
+#elif defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_2) |
|
727 |
+ return TLS_VER_1_1; |
|
728 |
+#else |
|
729 |
+ return TLS_VER_1_0; |
|
730 |
+#endif |
|
731 |
+} |
|
732 |
+ |
|
733 |
+/** |
|
734 |
+ * Convert an OpenVPN tls-version variable to mbed TLS format (i.e. a major and |
|
735 |
+ * minor ssl version number). |
|
736 |
+ * |
|
737 |
+ * @param tls_ver The tls-version variable to convert. |
|
738 |
+ * @param major Returns the TLS major version in mbed TLS format. |
|
739 |
+ * Must be a valid pointer. |
|
740 |
+ * @param minor Returns the TLS minor version in mbed TLS format. |
|
741 |
+ * Must be a valid pointer. |
|
742 |
+ */ |
|
743 |
+static void tls_version_to_major_minor(int tls_ver, int *major, int *minor) { |
|
744 |
+ ASSERT(major); |
|
745 |
+ ASSERT(minor); |
|
746 |
+ |
|
747 |
+ switch (tls_ver) |
|
748 |
+ { |
|
749 |
+ case TLS_VER_1_0: |
|
750 |
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
751 |
+ *minor = MBEDTLS_SSL_MINOR_VERSION_1; |
|
752 |
+ break; |
|
753 |
+ case TLS_VER_1_1: |
|
754 |
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
755 |
+ *minor = MBEDTLS_SSL_MINOR_VERSION_2; |
|
756 |
+ break; |
|
757 |
+ case TLS_VER_1_2: |
|
758 |
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
759 |
+ *minor = MBEDTLS_SSL_MINOR_VERSION_3; |
|
760 |
+ break; |
|
761 |
+ default: |
|
762 |
+ msg(M_FATAL, "%s: invalid TLS version %d", __func__, tls_ver); |
|
763 |
+ break; |
|
764 |
+ } |
|
765 |
+} |
|
766 |
+ |
|
767 |
+void key_state_ssl_init(struct key_state_ssl *ks_ssl, |
|
768 |
+ const struct tls_root_ctx *ssl_ctx, bool is_server, struct tls_session *session) |
|
769 |
+{ |
|
770 |
+ ASSERT(NULL != ssl_ctx); |
|
771 |
+ ASSERT(ks_ssl); |
|
772 |
+ CLEAR(*ks_ssl); |
|
773 |
+ |
|
774 |
+ /* Initialise SSL config */ |
|
775 |
+ mbedtls_ssl_config_init(&ks_ssl->ssl_config); |
|
776 |
+ mbedtls_ssl_config_defaults(&ks_ssl->ssl_config, ssl_ctx->endpoint, |
|
777 |
+ MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); |
|
778 |
+ mbedtls_debug_set_threshold(3); |
|
779 |
+ mbedtls_ssl_conf_dbg (&ks_ssl->ssl_config, my_debug, NULL); |
|
780 |
+ mbedtls_ssl_conf_rng (&ks_ssl->ssl_config, mbedtls_ctr_drbg_random, |
|
781 |
+ rand_ctx_get()); |
|
782 |
+ |
|
783 |
+ if (ssl_ctx->allowed_ciphers) |
|
784 |
+ mbedtls_ssl_conf_ciphersuites (&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers); |
|
785 |
+ |
|
786 |
+ /* Disable record splitting (for now). OpenVPN assumes records are sent |
|
787 |
+ * unfragmented, and changing that will require thorough review and |
|
788 |
+ * testing. Since OpenVPN is not susceptible to BEAST, we can just |
|
789 |
+ * disable record splitting as a quick fix. */ |
|
790 |
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
|
791 |
+ mbedtls_ssl_conf_cbc_record_splitting (&ks_ssl->ssl_config, |
|
792 |
+ MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED); |
|
793 |
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ |
|
794 |
+ |
|
795 |
+ /* Initialise authentication information */ |
|
796 |
+ if (is_server) |
|
797 |
+ mbed_ok (mbedtls_ssl_conf_dh_param_ctx(&ks_ssl->ssl_config, |
|
798 |
+ ssl_ctx->dhm_ctx)); |
|
799 |
+ |
|
800 |
+ mbed_ok (mbedtls_ssl_conf_own_cert(&ks_ssl->ssl_config, ssl_ctx->crt_chain, |
|
801 |
+ ssl_ctx->priv_key)); |
|
802 |
+ |
|
803 |
+ /* Initialise SSL verification */ |
|
804 |
+#if P2MP_SERVER |
|
805 |
+ if (session->opt->ssl_flags & SSLF_CLIENT_CERT_OPTIONAL) |
|
806 |
+ { |
|
807 |
+ mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL); |
|
808 |
+ } |
|
809 |
+ else if (!(session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)) |
|
810 |
+#endif |
|
811 |
+ { |
|
812 |
+ mbedtls_ssl_conf_authmode (&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_REQUIRED); |
|
813 |
+ } |
|
814 |
+ mbedtls_ssl_conf_verify (&ks_ssl->ssl_config, verify_callback, session); |
|
815 |
+ |
|
816 |
+ /* TODO: mbed TLS does not currently support sending the CA chain to the client */ |
|
817 |
+ mbedtls_ssl_conf_ca_chain (&ks_ssl->ssl_config, ssl_ctx->ca_chain, NULL ); |
|
818 |
+ |
|
819 |
+ /* Initialize minimum TLS version */ |
|
820 |
+ { |
|
821 |
+ const int tls_version_min = |
|
822 |
+ (session->opt->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & |
|
823 |
+ SSLF_TLS_VERSION_MIN_MASK; |
|
824 |
+ |
|
825 |
+ /* default to TLS 1.0 */ |
|
826 |
+ int major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
827 |
+ int minor = MBEDTLS_SSL_MINOR_VERSION_1; |
|
828 |
+ |
|
829 |
+ if (tls_version_min > TLS_VER_UNSPEC) |
|
830 |
+ tls_version_to_major_minor(tls_version_min, &major, &minor); |
|
831 |
+ |
|
832 |
+ mbedtls_ssl_conf_min_version(&ks_ssl->ssl_config, major, minor); |
|
833 |
+ } |
|
834 |
+ |
|
835 |
+ /* Initialize maximum TLS version */ |
|
836 |
+ { |
|
837 |
+ const int tls_version_max = |
|
838 |
+ (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & |
|
839 |
+ SSLF_TLS_VERSION_MAX_MASK; |
|
840 |
+ |
|
841 |
+ if (tls_version_max > TLS_VER_UNSPEC) |
|
842 |
+ { |
|
843 |
+ int major, minor; |
|
844 |
+ tls_version_to_major_minor(tls_version_max, &major, &minor); |
|
845 |
+ mbedtls_ssl_conf_max_version(&ks_ssl->ssl_config, major, minor); |
|
846 |
+ } |
|
847 |
+ } |
|
848 |
+ |
|
849 |
+ /* Initialise SSL context */ |
|
850 |
+ ALLOC_OBJ_CLEAR(ks_ssl->ctx, mbedtls_ssl_context); |
|
851 |
+ mbedtls_ssl_init(ks_ssl->ctx); |
|
852 |
+ mbedtls_ssl_setup(ks_ssl->ctx, &ks_ssl->ssl_config); |
|
853 |
+ |
|
854 |
+ /* Initialise BIOs */ |
|
855 |
+ CLEAR (ks_ssl->bio_ctx); |
|
856 |
+ mbedtls_ssl_set_bio (ks_ssl->ctx, &ks_ssl->bio_ctx, ssl_bio_write, |
|
857 |
+ ssl_bio_read, NULL); |
|
858 |
+} |
|
859 |
+ |
|
860 |
+void |
|
861 |
+key_state_ssl_free(struct key_state_ssl *ks_ssl) |
|
862 |
+{ |
|
863 |
+ if (ks_ssl) { |
|
864 |
+ if (ks_ssl->ctx) |
|
865 |
+ { |
|
866 |
+ mbedtls_ssl_free(ks_ssl->ctx); |
|
867 |
+ free(ks_ssl->ctx); |
|
868 |
+ } |
|
869 |
+ mbedtls_ssl_config_free(&ks_ssl->ssl_config); |
|
870 |
+ buf_free_entries(&ks_ssl->bio_ctx.in); |
|
871 |
+ buf_free_entries(&ks_ssl->bio_ctx.out); |
|
872 |
+ CLEAR(*ks_ssl); |
|
873 |
+ } |
|
874 |
+} |
|
875 |
+ |
|
876 |
+int |
|
877 |
+key_state_write_plaintext (struct key_state_ssl *ks, struct buffer *buf) |
|
878 |
+{ |
|
879 |
+ int retval = 0; |
|
880 |
+ |
|
881 |
+ ASSERT (buf); |
|
882 |
+ |
|
883 |
+ retval = key_state_write_plaintext_const(ks, BPTR(buf), BLEN(buf)); |
|
884 |
+ |
|
885 |
+ if (1 == retval) |
|
886 |
+ { |
|
887 |
+ memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */ |
|
888 |
+ buf->len = 0; |
|
889 |
+ } |
|
890 |
+ |
|
891 |
+ return retval; |
|
892 |
+} |
|
893 |
+ |
|
894 |
+int |
|
895 |
+key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data, int len) |
|
896 |
+{ |
|
897 |
+ int retval = 0; |
|
898 |
+ perf_push (PERF_BIO_WRITE_PLAINTEXT); |
|
899 |
+ |
|
900 |
+ ASSERT (NULL != ks); |
|
901 |
+ ASSERT (len >= 0); |
|
902 |
+ |
|
903 |
+ if (0 == len) |
|
904 |
+ { |
|
905 |
+ perf_pop (); |
|
906 |
+ return 0; |
|
907 |
+ } |
|
908 |
+ |
|
909 |
+ ASSERT (data); |
|
910 |
+ |
|
911 |
+ retval = mbedtls_ssl_write(ks->ctx, data, len); |
|
912 |
+ |
|
913 |
+ if (retval < 0) |
|
914 |
+ { |
|
915 |
+ perf_pop (); |
|
916 |
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
917 |
+ return 0; |
|
918 |
+ mbed_log_err (D_TLS_ERRORS, retval, |
|
919 |
+ "TLS ERROR: write tls_write_plaintext_const error"); |
|
920 |
+ return -1; |
|
921 |
+ } |
|
922 |
+ |
|
923 |
+ if (retval != len) |
|
924 |
+ { |
|
925 |
+ msg (D_TLS_ERRORS, |
|
926 |
+ "TLS ERROR: write tls_write_plaintext_const incomplete %d/%d", |
|
927 |
+ retval, len); |
|
928 |
+ perf_pop (); |
|
929 |
+ return -1; |
|
930 |
+ } |
|
931 |
+ |
|
932 |
+ /* successful write */ |
|
933 |
+ dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_plaintext_const %d bytes", retval); |
|
934 |
+ |
|
935 |
+ perf_pop (); |
|
936 |
+ return 1; |
|
937 |
+} |
|
938 |
+ |
|
939 |
+int |
|
940 |
+key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf, |
|
941 |
+ int maxlen) |
|
942 |
+{ |
|
943 |
+ int retval = 0; |
|
944 |
+ int len = 0; |
|
945 |
+ |
|
946 |
+ perf_push (PERF_BIO_READ_CIPHERTEXT); |
|
947 |
+ |
|
948 |
+ ASSERT (NULL != ks); |
|
949 |
+ ASSERT (buf); |
|
950 |
+ ASSERT (buf->len >= 0); |
|
951 |
+ |
|
952 |
+ if (buf->len) |
|
953 |
+ { |
|
954 |
+ perf_pop (); |
|
955 |
+ return 0; |
|
956 |
+ } |
|
957 |
+ |
|
958 |
+ len = buf_forward_capacity (buf); |
|
959 |
+ if (maxlen < len) |
|
960 |
+ len = maxlen; |
|
961 |
+ |
|
962 |
+ retval = endless_buf_read(&ks->bio_ctx.out, BPTR(buf), len); |
|
963 |
+ |
|
964 |
+ /* Error during read, check for retry error */ |
|
965 |
+ if (retval < 0) |
|
966 |
+ { |
|
967 |
+ perf_pop (); |
|
968 |
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
969 |
+ return 0; |
|
970 |
+ mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_ciphertext error"); |
|
971 |
+ buf->len = 0; |
|
972 |
+ return -1; |
|
973 |
+ } |
|
974 |
+ /* Nothing read, try again */ |
|
975 |
+ if (0 == retval) |
|
976 |
+ { |
|
977 |
+ buf->len = 0; |
|
978 |
+ perf_pop (); |
|
979 |
+ return 0; |
|
980 |
+ } |
|
981 |
+ |
|
982 |
+ /* successful read */ |
|
983 |
+ dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_ciphertext %d bytes", retval); |
|
984 |
+ buf->len = retval; |
|
985 |
+ perf_pop (); |
|
986 |
+ return 1; |
|
987 |
+} |
|
988 |
+ |
|
989 |
+int |
|
990 |
+key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf) |
|
991 |
+{ |
|
992 |
+ int retval = 0; |
|
993 |
+ perf_push (PERF_BIO_WRITE_CIPHERTEXT); |
|
994 |
+ |
|
995 |
+ ASSERT (NULL != ks); |
|
996 |
+ ASSERT (buf); |
|
997 |
+ ASSERT (buf->len >= 0); |
|
998 |
+ |
|
999 |
+ if (0 == buf->len) |
|
1000 |
+ { |
|
1001 |
+ perf_pop (); |
|
1002 |
+ return 0; |
|
1003 |
+ } |
|
1004 |
+ |
|
1005 |
+ retval = endless_buf_write(&ks->bio_ctx.in, BPTR(buf), buf->len); |
|
1006 |
+ |
|
1007 |
+ if (retval < 0) |
|
1008 |
+ { |
|
1009 |
+ perf_pop (); |
|
1010 |
+ |
|
1011 |
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
1012 |
+ return 0; |
|
1013 |
+ mbed_log_err (D_TLS_ERRORS, retval, |
|
1014 |
+ "TLS ERROR: write tls_write_ciphertext error"); |
|
1015 |
+ return -1; |
|
1016 |
+ } |
|
1017 |
+ |
|
1018 |
+ if (retval != buf->len) |
|
1019 |
+ { |
|
1020 |
+ msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext incomplete %d/%d", |
|
1021 |
+ retval, buf->len); |
|
1022 |
+ perf_pop (); |
|
1023 |
+ return -1; |
|
1024 |
+ } |
|
1025 |
+ |
|
1026 |
+ /* successful write */ |
|
1027 |
+ dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_ciphertext %d bytes", retval); |
|
1028 |
+ |
|
1029 |
+ memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */ |
|
1030 |
+ buf->len = 0; |
|
1031 |
+ |
|
1032 |
+ perf_pop (); |
|
1033 |
+ return 1; |
|
1034 |
+} |
|
1035 |
+ |
|
1036 |
+int |
|
1037 |
+key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf, |
|
1038 |
+ int maxlen) |
|
1039 |
+{ |
|
1040 |
+ int retval = 0; |
|
1041 |
+ int len = 0; |
|
1042 |
+ |
|
1043 |
+ perf_push (PERF_BIO_READ_PLAINTEXT); |
|
1044 |
+ |
|
1045 |
+ ASSERT (NULL != ks); |
|
1046 |
+ ASSERT (buf); |
|
1047 |
+ ASSERT (buf->len >= 0); |
|
1048 |
+ |
|
1049 |
+ if (buf->len) |
|
1050 |
+ { |
|
1051 |
+ perf_pop (); |
|
1052 |
+ return 0; |
|
1053 |
+ } |
|
1054 |
+ |
|
1055 |
+ len = buf_forward_capacity (buf); |
|
1056 |
+ if (maxlen < len) |
|
1057 |
+ len = maxlen; |
|
1058 |
+ |
|
1059 |
+ retval = mbedtls_ssl_read(ks->ctx, BPTR(buf), len); |
|
1060 |
+ |
|
1061 |
+ /* Error during read, check for retry error */ |
|
1062 |
+ if (retval < 0) |
|
1063 |
+ { |
|
1064 |
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
1065 |
+ return 0; |
|
1066 |
+ mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_plaintext error"); |
|
1067 |
+ buf->len = 0; |
|
1068 |
+ perf_pop (); |
|
1069 |
+ return -1; |
|
1070 |
+ } |
|
1071 |
+ /* Nothing read, try again */ |
|
1072 |
+ if (0 == retval) |
|
1073 |
+ { |
|
1074 |
+ buf->len = 0; |
|
1075 |
+ perf_pop (); |
|
1076 |
+ return 0; |
|
1077 |
+ } |
|
1078 |
+ |
|
1079 |
+ /* successful read */ |
|
1080 |
+ dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_plaintext %d bytes", retval); |
|
1081 |
+ buf->len = retval; |
|
1082 |
+ |
|
1083 |
+ perf_pop (); |
|
1084 |
+ return 1; |
|
1085 |
+} |
|
1086 |
+ |
|
1087 |
+/* ************************************** |
|
1088 |
+ * |
|
1089 |
+ * Information functions |
|
1090 |
+ * |
|
1091 |
+ * Print information for the end user. |
|
1092 |
+ * |
|
1093 |
+ ***************************************/ |
|
1094 |
+void |
|
1095 |
+print_details (struct key_state_ssl * ks_ssl, const char *prefix) |
|
1096 |
+{ |
|
1097 |
+ const mbedtls_x509_crt *cert; |
|
1098 |
+ char s1[256]; |
|
1099 |
+ char s2[256]; |
|
1100 |
+ |
|
1101 |
+ s1[0] = s2[0] = 0; |
|
1102 |
+ openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s", |
|
1103 |
+ prefix, |
|
1104 |
+ mbedtls_ssl_get_version (ks_ssl->ctx), |
|
1105 |
+ mbedtls_ssl_get_ciphersuite (ks_ssl->ctx)); |
|
1106 |
+ |
|
1107 |
+ cert = mbedtls_ssl_get_peer_cert (ks_ssl->ctx); |
|
1108 |
+ if (cert != NULL) |
|
1109 |
+ { |
|
1110 |
+ openvpn_snprintf (s2, sizeof (s2), ", %zu bit key", |
|
1111 |
+ mbedtls_pk_get_bitlen (&cert->pk)); |
|
1112 |
+ } |
|
1113 |
+ |
|
1114 |
+ msg (D_HANDSHAKE, "%s%s", s1, s2); |
|
1115 |
+} |
|
1116 |
+ |
|
1117 |
+void |
|
1118 |
+show_available_tls_ciphers (const char *cipher_list) |
|
1119 |
+{ |
|
1120 |
+ struct tls_root_ctx tls_ctx; |
|
1121 |
+ const int *ciphers = mbedtls_ssl_list_ciphersuites (); |
|
1122 |
+ |
|
1123 |
+ tls_ctx_server_new(&tls_ctx); |
|
1124 |
+ tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); |
|
1125 |
+ |
|
1126 |
+ if (tls_ctx.allowed_ciphers) |
|
1127 |
+ ciphers = tls_ctx.allowed_ciphers; |
|
1128 |
+ |
|
1129 |
+#ifndef ENABLE_SMALL |
|
1130 |
+ printf ("Available TLS Ciphers,\n"); |
|
1131 |
+ printf ("listed in order of preference:\n\n"); |
|
1132 |
+#endif |
|
1133 |
+ |
|
1134 |
+ while (*ciphers != 0) |
|
1135 |
+ { |
|
1136 |
+ printf ("%s\n", mbedtls_ssl_get_ciphersuite_name (*ciphers)); |
|
1137 |
+ ciphers++; |
|
1138 |
+ } |
|
1139 |
+ printf ("\n" SHOW_TLS_CIPHER_LIST_WARNING); |
|
1140 |
+ |
|
1141 |
+ tls_ctx_free(&tls_ctx); |
|
1142 |
+} |
|
1143 |
+ |
|
1144 |
+void |
|
1145 |
+show_available_curves (void) |
|
1146 |
+{ |
|
1147 |
+ const mbedtls_ecp_curve_info *pcurve = mbedtls_ecp_curve_list (); |
|
1148 |
+ |
|
1149 |
+ if (NULL == pcurve) |
|
1150 |
+ msg (M_FATAL, "Cannot retrieve curve list from mbed TLS"); |
|
1151 |
+ |
|
1152 |
+ /* Print curve list */ |
|
1153 |
+ printf ("Available Elliptic curves, listed in order of preference:\n\n"); |
|
1154 |
+ while (MBEDTLS_ECP_DP_NONE != pcurve->grp_id) |
|
1155 |
+ { |
|
1156 |
+ printf("%s\n", pcurve->name); |
|
1157 |
+ pcurve++; |
|
1158 |
+ } |
|
1159 |
+} |
|
1160 |
+ |
|
1161 |
+void |
|
1162 |
+get_highest_preference_tls_cipher (char *buf, int size) |
|
1163 |
+{ |
|
1164 |
+ const char *cipher_name; |
|
1165 |
+ const int *ciphers = mbedtls_ssl_list_ciphersuites(); |
|
1166 |
+ if (*ciphers == 0) |
|
1167 |
+ msg (M_FATAL, "Cannot retrieve list of supported SSL ciphers."); |
|
1168 |
+ |
|
1169 |
+ cipher_name = mbedtls_ssl_get_ciphersuite_name(*ciphers); |
|
1170 |
+ strncpynt (buf, cipher_name, size); |
|
1171 |
+} |
|
1172 |
+ |
|
1173 |
+const char * |
|
1174 |
+get_ssl_library_version(void) |
|
1175 |
+{ |
|
1176 |
+ static char mbedtls_version[30]; |
|
1177 |
+ unsigned int pv = mbedtls_version_get_number(); |
|
1178 |
+ sprintf( mbedtls_version, "mbed TLS %d.%d.%d", |
|
1179 |
+ (pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff ); |
|
1180 |
+ return mbedtls_version; |
|
1181 |
+} |
|
1182 |
+ |
|
1183 |
+#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) */ |
0 | 1184 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,92 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
9 |
+ * |
|
10 |
+ * This program is free software; you can redistribute it and/or modify |
|
11 |
+ * it under the terms of the GNU General Public License version 2 |
|
12 |
+ * as published by the Free Software Foundation. |
|
13 |
+ * |
|
14 |
+ * This program is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 |
+ * GNU General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU General Public License |
|
20 |
+ * along with this program (see the file COPYING included with this |
|
21 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
22 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
23 |
+ */ |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @file Control Channel mbed TLS Backend |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+#ifndef SSL_MBEDTLS_H_ |
|
30 |
+#define SSL_MBEDTLS_H_ |
|
31 |
+ |
|
32 |
+#include "syshead.h" |
|
33 |
+ |
|
34 |
+#include <mbedtls/ssl.h> |
|
35 |
+#include <mbedtls/x509_crt.h> |
|
36 |
+ |
|
37 |
+#if defined(ENABLE_PKCS11) |
|
38 |
+#include <mbedtls/pkcs11.h> |
|
39 |
+#endif |
|
40 |
+ |
|
41 |
+typedef struct _buffer_entry buffer_entry; |
|
42 |
+ |
|
43 |
+struct _buffer_entry { |
|
44 |
+ size_t length; |
|
45 |
+ uint8_t *data; |
|
46 |
+ buffer_entry *next_block; |
|
47 |
+}; |
|
48 |
+ |
|
49 |
+typedef struct { |
|
50 |
+ size_t data_start; |
|
51 |
+ buffer_entry *first_block; |
|
52 |
+ buffer_entry *last_block; |
|
53 |
+} endless_buffer; |
|
54 |
+ |
|
55 |
+typedef struct { |
|
56 |
+ endless_buffer in; |
|
57 |
+ endless_buffer out; |
|
58 |
+} bio_ctx; |
|
59 |
+ |
|
60 |
+/** |
|
61 |
+ * Structure that wraps the TLS context. Contents differ depending on the |
|
62 |
+ * SSL library used. |
|
63 |
+ * |
|
64 |
+ * Either \c priv_key_pkcs11 or \c priv_key must be filled in. |
|
65 |
+ */ |
|
66 |
+struct tls_root_ctx { |
|
67 |
+ bool initialised; /**< True if the context has been initialised */ |
|
68 |
+ |
|
69 |
+ int endpoint; /**< Whether or not this is a server or a client */ |
|
70 |
+ |
|
71 |
+ mbedtls_dhm_context *dhm_ctx; /**< Diffie-Helmann-Merkle context */ |
|
72 |
+ mbedtls_x509_crt *crt_chain; /**< Local Certificate chain */ |
|
73 |
+ mbedtls_x509_crt *ca_chain; /**< CA chain for remote verification */ |
|
74 |
+ mbedtls_pk_context *priv_key; /**< Local private key */ |
|
75 |
+#if defined(ENABLE_PKCS11) |
|
76 |
+ mbedtls_pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */ |
|
77 |
+#endif |
|
78 |
+#ifdef MANAGMENT_EXTERNAL_KEY |
|
79 |
+ struct external_context *external_key; /**< Management external key */ |
|
80 |
+#endif |
|
81 |
+ int * allowed_ciphers; /**< List of allowed ciphers for this connection */ |
|
82 |
+}; |
|
83 |
+ |
|
84 |
+struct key_state_ssl { |
|
85 |
+ mbedtls_ssl_config ssl_config; /**< mbedTLS global ssl config */ |
|
86 |
+ mbedtls_ssl_context *ctx; /**< mbedTLS connection context */ |
|
87 |
+ bio_ctx bio_ctx; |
|
88 |
+}; |
|
89 |
+ |
|
90 |
+ |
|
91 |
+#endif /* SSL_MBEDTLS_H_ */ |
0 | 92 |
deleted file mode 100644 |
... | ... |
@@ -1,1184 +0,0 @@ |
1 |
-/* |
|
2 |
- * OpenVPN -- An application to securely tunnel IP networks |
|
3 |
- * over a single TCP/UDP port, with support for SSL/TLS-based |
|
4 |
- * session authentication and key exchange, |
|
5 |
- * packet encryption, packet authentication, and |
|
6 |
- * packet compression. |
|
7 |
- * |
|
8 |
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
9 |
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
10 |
- * Copyright (C) 2006-2010, Brainspark B.V. |
|
11 |
- * |
|
12 |
- * This program is free software; you can redistribute it and/or modify |
|
13 |
- * it under the terms of the GNU General Public License version 2 |
|
14 |
- * as published by the Free Software Foundation. |
|
15 |
- * |
|
16 |
- * This program is distributed in the hope that it will be useful, |
|
17 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
18 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
19 |
- * GNU General Public License for more details. |
|
20 |
- * |
|
21 |
- * You should have received a copy of the GNU General Public License |
|
22 |
- * along with this program (see the file COPYING included with this |
|
23 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
24 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
25 |
- */ |
|
26 |
- |
|
27 |
-/** |
|
28 |
- * @file Control Channel mbed TLS Backend |
|
29 |
- */ |
|
30 |
- |
|
31 |
-#ifdef HAVE_CONFIG_H |
|
32 |
-#include "config.h" |
|
33 |
-#elif defined(_MSC_VER) |
|
34 |
-#include "config-msvc.h" |
|
35 |
-#endif |
|
36 |
- |
|
37 |
-#include "syshead.h" |
|
38 |
- |
|
39 |
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
40 |
- |
|
41 |
-#include "errlevel.h" |
|
42 |
-#include "ssl_backend.h" |
|
43 |
-#include "base64.h" |
|
44 |
-#include "buffer.h" |
|
45 |
-#include "misc.h" |
|
46 |
-#include "manage.h" |
|
47 |
-#include "ssl_common.h" |
|
48 |
- |
|
49 |
-#include <mbedtls/havege.h> |
|
50 |
- |
|
51 |
-#include "ssl_verify_polarssl.h" |
|
52 |
-#include <mbedtls/debug.h> |
|
53 |
-#include <mbedtls/error.h> |
|
54 |
-#include <mbedtls/net.h> |
|
55 |
-#include <mbedtls/oid.h> |
|
56 |
-#include <mbedtls/pem.h> |
|
57 |
-#include <mbedtls/sha256.h> |
|
58 |
-#include <mbedtls/version.h> |
|
59 |
- |
|
60 |
-void |
|
61 |
-tls_init_lib() |
|
62 |
-{ |
|
63 |
-} |
|
64 |
- |
|
65 |
-void |
|
66 |
-tls_free_lib() |
|
67 |
-{ |
|
68 |
-} |
|
69 |
- |
|
70 |
-void |
|
71 |
-tls_clear_error() |
|
72 |
-{ |
|
73 |
-} |
|
74 |
- |
|
75 |
-void |
|
76 |
-tls_ctx_server_new(struct tls_root_ctx *ctx) |
|
77 |
-{ |
|
78 |
- ASSERT(NULL != ctx); |
|
79 |
- CLEAR(*ctx); |
|
80 |
- |
|
81 |
- ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context); |
|
82 |
- |
|
83 |
- ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt); |
|
84 |
- |
|
85 |
- ctx->endpoint = MBEDTLS_SSL_IS_SERVER; |
|
86 |
- ctx->initialised = true; |
|
87 |
-} |
|
88 |
- |
|
89 |
-void |
|
90 |
-tls_ctx_client_new(struct tls_root_ctx *ctx) |
|
91 |
-{ |
|
92 |
- ASSERT(NULL != ctx); |
|
93 |
- CLEAR(*ctx); |
|
94 |
- |
|
95 |
- ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context); |
|
96 |
- ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt); |
|
97 |
- |
|
98 |
- ctx->endpoint = MBEDTLS_SSL_IS_CLIENT; |
|
99 |
- ctx->initialised = true; |
|
100 |
-} |
|
101 |
- |
|
102 |
-void |
|
103 |
-tls_ctx_free(struct tls_root_ctx *ctx) |
|
104 |
-{ |
|
105 |
- if (ctx) |
|
106 |
- { |
|
107 |
- mbedtls_pk_free(ctx->priv_key); |
|
108 |
- if (ctx->priv_key) |
|
109 |
- free(ctx->priv_key); |
|
110 |
- |
|
111 |
- mbedtls_x509_crt_free(ctx->ca_chain); |
|
112 |
- if (ctx->ca_chain) |
|
113 |
- free(ctx->ca_chain); |
|
114 |
- |
|
115 |
- mbedtls_x509_crt_free(ctx->crt_chain); |
|
116 |
- if (ctx->crt_chain) |
|
117 |
- free(ctx->crt_chain); |
|
118 |
- |
|
119 |
- mbedtls_dhm_free(ctx->dhm_ctx); |
|
120 |
- if (ctx->dhm_ctx) |
|
121 |
- free(ctx->dhm_ctx); |
|
122 |
- |
|
123 |
-#if defined(ENABLE_PKCS11) |
|
124 |
- if (ctx->priv_key_pkcs11 != NULL) { |
|
125 |
- mbedtls_pkcs11_priv_key_free(ctx->priv_key_pkcs11); |
|
126 |
- free(ctx->priv_key_pkcs11); |
|
127 |
- } |
|
128 |
-#endif |
|
129 |
-#if defined(MANAGMENT_EXTERNAL_KEY) |
|
130 |
- if (ctx->external_key != NULL) |
|
131 |
- free(ctx->external_key); |
|
132 |
-#endif |
|
133 |
- |
|
134 |
- if (ctx->allowed_ciphers) |
|
135 |
- free(ctx->allowed_ciphers); |
|
136 |
- |
|
137 |
- CLEAR(*ctx); |
|
138 |
- |
|
139 |
- ctx->initialised = false; |
|
140 |
- |
|
141 |
- } |
|
142 |
-} |
|
143 |
- |
|
144 |
-bool |
|
145 |
-tls_ctx_initialised(struct tls_root_ctx *ctx) |
|
146 |
-{ |
|
147 |
- ASSERT(NULL != ctx); |
|
148 |
- return ctx->initialised; |
|
149 |
-} |
|
150 |
- |
|
151 |
-void |
|
152 |
-key_state_export_keying_material(struct key_state_ssl *ssl, |
|
153 |
- struct tls_session *session) |
|
154 |
-{ |
|
155 |
-} |
|
156 |
- |
|
157 |
-void |
|
158 |
-tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) |
|
159 |
-{ |
|
160 |
-} |
|
161 |
- |
|
162 |
-static const char * |
|
163 |
-tls_translate_cipher_name (const char * cipher_name) { |
|
164 |
- const tls_cipher_name_pair * pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name)); |
|
165 |
- |
|
166 |
- if (NULL == pair) |
|
167 |
- { |
|
168 |
- // No translation found, return original |
|
169 |
- return cipher_name; |
|
170 |
- } |
|
171 |
- |
|
172 |
- if (0 != strcmp(cipher_name, pair->iana_name)) |
|
173 |
- { |
|
174 |
- // Deprecated name found, notify user |
|
175 |
- msg(M_WARN, "Deprecated cipher suite name '%s', please use IANA name '%s'", pair->openssl_name, pair->iana_name); |
|
176 |
- } |
|
177 |
- |
|
178 |
- return pair->iana_name; |
|
179 |
-} |
|
180 |
- |
|
181 |
-void |
|
182 |
-tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) |
|
183 |
-{ |
|
184 |
- char *tmp_ciphers, *tmp_ciphers_orig, *token; |
|
185 |
- int i, cipher_count; |
|
186 |
- int ciphers_len; |
|
187 |
- |
|
188 |
- if (NULL == ciphers) |
|
189 |
- return; /* Nothing to do */ |
|
190 |
- |
|
191 |
- ciphers_len = strlen (ciphers); |
|
192 |
- |
|
193 |
- ASSERT (NULL != ctx); |
|
194 |
- ASSERT (0 != ciphers_len); |
|
195 |
- |
|
196 |
- /* Get number of ciphers */ |
|
197 |
- for (i = 0, cipher_count = 1; i < ciphers_len; i++) |
|
198 |
- if (ciphers[i] == ':') |
|
199 |
- cipher_count++; |
|
200 |
- |
|
201 |
- /* Allocate an array for them */ |
|
202 |
- ALLOC_ARRAY_CLEAR(ctx->allowed_ciphers, int, cipher_count+1) |
|
203 |
- |
|
204 |
- /* Parse allowed ciphers, getting IDs */ |
|
205 |
- i = 0; |
|
206 |
- tmp_ciphers_orig = tmp_ciphers = string_alloc (ciphers, NULL); |
|
207 |
- |
|
208 |
- token = strtok (tmp_ciphers, ":"); |
|
209 |
- while(token) |
|
210 |
- { |
|
211 |
- ctx->allowed_ciphers[i] = mbedtls_ssl_get_ciphersuite_id ( |
|
212 |
- tls_translate_cipher_name (token)); |
|
213 |
- if (0 != ctx->allowed_ciphers[i]) |
|
214 |
- i++; |
|
215 |
- token = strtok (NULL, ":"); |
|
216 |
- } |
|
217 |
- free(tmp_ciphers_orig); |
|
218 |
-} |
|
219 |
- |
|
220 |
-void |
|
221 |
-tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) |
|
222 |
-{ |
|
223 |
- ASSERT (ctx); |
|
224 |
- if (ctx->crt_chain == NULL) |
|
225 |
- { |
|
226 |
- return; /* Nothing to check if there is no certificate */ |
|
227 |
- } |
|
228 |
- |
|
229 |
- if (mbedtls_x509_time_is_future (&ctx->crt_chain->valid_from)) |
|
230 |
- { |
|
231 |
- msg (M_WARN, "WARNING: Your certificate is not yet valid!"); |
|
232 |
- } |
|
233 |
- |
|
234 |
- if (mbedtls_x509_time_is_past (&ctx->crt_chain->valid_to)) |
|
235 |
- { |
|
236 |
- msg (M_WARN, "WARNING: Your certificate has expired!"); |
|
237 |
- } |
|
238 |
-} |
|
239 |
- |
|
240 |
-void |
|
241 |
-tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, |
|
242 |
- const char *dh_inline |
|
243 |
- ) |
|
244 |
-{ |
|
245 |
- if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline) |
|
246 |
- { |
|
247 |
- if (!mbed_ok(mbedtls_dhm_parse_dhm(ctx->dhm_ctx, |
|
248 |
- (const unsigned char *) dh_inline, strlen(dh_inline)+1))) |
|
249 |
- msg (M_FATAL, "Cannot read inline DH parameters"); |
|
250 |
- } |
|
251 |
-else |
|
252 |
- { |
|
253 |
- if (!mbed_ok(mbedtls_dhm_parse_dhmfile(ctx->dhm_ctx, dh_file))) |
|
254 |
- msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file); |
|
255 |
- } |
|
256 |
- |
|
257 |
- msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with " counter_format " bit key", |
|
258 |
- (counter_type) 8 * mbedtls_mpi_size(&ctx->dhm_ctx->P)); |
|
259 |
-} |
|
260 |
- |
|
261 |
-void |
|
262 |
-tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name |
|
263 |
- ) |
|
264 |
-{ |
|
265 |
- if (NULL != curve_name) |
|
266 |
- msg(M_WARN, "WARNING: mbed TLS builds do not support specifying an ECDH " |
|
267 |
- "curve, using default curves."); |
|
268 |
-} |
|
269 |
- |
|
270 |
-int |
|
271 |
-tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, |
|
272 |
- const char *pkcs12_file_inline, |
|
273 |
- bool load_ca_file |
|
274 |
- ) |
|
275 |
-{ |
|
276 |
- msg(M_FATAL, "PKCS #12 files not yet supported for mbed TLS."); |
|
277 |
- return 0; |
|
278 |
-} |
|
279 |
- |
|
280 |
-#ifdef ENABLE_CRYPTOAPI |
|
281 |
-void |
|
282 |
-tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert) |
|
283 |
-{ |
|
284 |
- msg(M_FATAL, "Windows CryptoAPI not yet supported for mbed TLS."); |
|
285 |
-} |
|
286 |
-#endif /* WIN32 */ |
|
287 |
- |
|
288 |
-void |
|
289 |
-tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, |
|
290 |
- const char *cert_inline |
|
291 |
- ) |
|
292 |
-{ |
|
293 |
- ASSERT(NULL != ctx); |
|
294 |
- |
|
295 |
- if (!ctx->crt_chain) |
|
296 |
- { |
|
297 |
- ALLOC_OBJ_CLEAR(ctx->crt_chain, mbedtls_x509_crt); |
|
298 |
- } |
|
299 |
- |
|
300 |
- if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline) |
|
301 |
- { |
|
302 |
- if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain, |
|
303 |
- (const unsigned char *) cert_inline, strlen(cert_inline)+1))) |
|
304 |
- msg (M_FATAL, "Cannot load inline certificate file"); |
|
305 |
- } |
|
306 |
- else |
|
307 |
- { |
|
308 |
- if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, cert_file))) |
|
309 |
- { |
|
310 |
- msg (M_FATAL, "Cannot load certificate file %s", cert_file); |
|
311 |
- } |
|
312 |
- } |
|
313 |
-} |
|
314 |
- |
|
315 |
-int |
|
316 |
-tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, |
|
317 |
- const char *priv_key_inline |
|
318 |
- ) |
|
319 |
-{ |
|
320 |
- int status; |
|
321 |
- ASSERT(NULL != ctx); |
|
322 |
- |
|
323 |
- if (!ctx->priv_key) |
|
324 |
- { |
|
325 |
- ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context); |
|
326 |
- } |
|
327 |
- |
|
328 |
- if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_inline) |
|
329 |
- { |
|
330 |
- status = mbedtls_pk_parse_key(ctx->priv_key, |
|
331 |
- (const unsigned char *) priv_key_inline, strlen(priv_key_inline)+1, |
|
332 |
- NULL, 0); |
|
333 |
- |
|
334 |
- if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status) |
|
335 |
- { |
|
336 |
- char passbuf[512] = {0}; |
|
337 |
- pem_password_callback(passbuf, 512, 0, NULL); |
|
338 |
- status = mbedtls_pk_parse_key(ctx->priv_key, |
|
339 |
- (const unsigned char *) priv_key_inline, |
|
340 |
- strlen(priv_key_inline)+1, (unsigned char *) passbuf, |
|
341 |
- strlen(passbuf)); |
|
342 |
- } |
|
343 |
- } |
|
344 |
- else |
|
345 |
- { |
|
346 |
- status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL); |
|
347 |
- if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status) |
|
348 |
- { |
|
349 |
- char passbuf[512] = {0}; |
|
350 |
- pem_password_callback(passbuf, 512, 0, NULL); |
|
351 |
- status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf); |
|
352 |
- } |
|
353 |
- } |
|
354 |
- if (!mbed_ok(status)) |
|
355 |
- { |
|
356 |
-#ifdef ENABLE_MANAGEMENT |
|
357 |
- if (management && (MBEDTLS_ERR_PK_PASSWORD_MISMATCH == status)) |
|
358 |
- management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); |
|
359 |
-#endif |
|
360 |
- msg (M_WARN, "Cannot load private key file %s", priv_key_file); |
|
361 |
- return 1; |
|
362 |
- } |
|
363 |
- |
|
364 |
- warn_if_group_others_accessible (priv_key_file); |
|
365 |
- |
|
366 |
- /* TODO: Check Private Key */ |
|
367 |
-#if 0 |
|
368 |
- if (!SSL_CTX_check_private_key (ctx)) |
|
369 |
- msg (M_SSLERR, "Private key does not match the certificate"); |
|
370 |
-#endif |
|
371 |
- return 0; |
|
372 |
-} |
|
373 |
- |
|
374 |
-#ifdef MANAGMENT_EXTERNAL_KEY |
|
375 |
- |
|
376 |
- |
|
377 |
-struct external_context { |
|
378 |
- size_t signature_length; |
|
379 |
-}; |
|
380 |
- |
|
381 |
-/** |
|
382 |
- * external_pkcs1_sign implements a mbed TLS rsa_sign_func callback, that uses |
|
383 |
- * the management interface to request an RSA signature for the supplied hash. |
|
384 |
- * |
|
385 |
- * @param ctx_voidptr Management external key context. |
|
386 |
- * @param f_rng (Unused) |
|
387 |
- * @param p_rng (Unused) |
|
388 |
- * @param mode RSA mode (should be RSA_PRIVATE). |
|
389 |
- * @param md_alg Message digest ('hash') algorithm type. |
|
390 |
- * @param hashlen Length of hash (overridden by length specified by md_alg |
|
391 |
- * if md_alg != MBEDTLS_MD_NONE). |
|
392 |
- * @param hash The digest ('hash') to sign. Should have a size |
|
393 |
- * matching the length of md_alg (if != MBEDTLS_MD_NONE), |
|
394 |
- * or hashlen otherwise. |
|
395 |
- * @param sig Buffer that returns the signature. Should be at least of |
|
396 |
- * size ctx->signature_length. |
|
397 |
- * |
|
398 |
- * @return 0 on success, non-zero mbed TLS error code on failure. |
|
399 |
- */ |
|
400 |
-static inline int external_pkcs1_sign( void *ctx_voidptr, |
|
401 |
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, |
|
402 |
- mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, |
|
403 |
- unsigned char *sig ) |
|
404 |
-{ |
|
405 |
- struct external_context * const ctx = ctx_voidptr; |
|
406 |
- char *in_b64 = NULL; |
|
407 |
- char *out_b64 = NULL; |
|
408 |
- int rv; |
|
409 |
- unsigned char *p = sig; |
|
410 |
- size_t asn_len = 0, oid_size = 0, sig_len = 0; |
|
411 |
- const char *oid = NULL; |
|
412 |
- |
|
413 |
- if( NULL == ctx ) |
|
414 |
- return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
415 |
- |
|
416 |
- if( MBEDTLS_RSA_PRIVATE != mode ) |
|
417 |
- return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
418 |
- |
|
419 |
- /* |
|
420 |
- * Support a wide range of hashes. TLSv1.1 and before only need SIG_RSA_RAW, |
|
421 |
- * but TLSv1.2 needs the full suite of hashes. |
|
422 |
- * |
|
423 |
- * This code has been taken from mbed TLS pkcs11_sign(), under the GPLv2.0+. |
|
424 |
- */ |
|
425 |
- if( md_alg != MBEDTLS_MD_NONE ) |
|
426 |
- { |
|
427 |
- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); |
|
428 |
- if( md_info == NULL ) |
|
429 |
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
|
430 |
- |
|
431 |
- if (!mbed_ok(mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ))) |
|
432 |
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
|
433 |
- |
|
434 |
- hashlen = mbedtls_md_get_size( md_info ); |
|
435 |
- asn_len = 10 + oid_size; |
|
436 |
- } |
|
437 |
- |
|
438 |
- sig_len = ctx->signature_length; |
|
439 |
- if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len ) |
|
440 |
- return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
441 |
- |
|
442 |
- if( md_alg != MBEDTLS_MD_NONE ) |
|
443 |
- { |
|
444 |
- /* |
|
445 |
- * DigestInfo ::= SEQUENCE { |
|
446 |
- * digestAlgorithm DigestAlgorithmIdentifier, |
|
447 |
- * digest Digest } |
|
448 |
- * |
|
449 |
- * DigestAlgorithmIdentifier ::= AlgorithmIdentifier |
|
450 |
- * |
|
451 |
- * Digest ::= OCTET STRING |
|
452 |
- */ |
|
453 |
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
|
454 |
- *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); |
|
455 |
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
|
456 |
- *p++ = (unsigned char) ( 0x04 + oid_size ); |
|
457 |
- *p++ = MBEDTLS_ASN1_OID; |
|
458 |
- *p++ = oid_size & 0xFF; |
|
459 |
- memcpy( p, oid, oid_size ); |
|
460 |
- p += oid_size; |
|
461 |
- *p++ = MBEDTLS_ASN1_NULL; |
|
462 |
- *p++ = 0x00; |
|
463 |
- *p++ = MBEDTLS_ASN1_OCTET_STRING; |
|
464 |
- *p++ = hashlen; |
|
465 |
- |
|
466 |
- /* Determine added ASN length */ |
|
467 |
- asn_len = p - sig; |
|
468 |
- } |
|
469 |
- |
|
470 |
- /* Copy the hash to be signed */ |
|
471 |
- memcpy( p, hash, hashlen ); |
|
472 |
- |
|
473 |
- /* convert 'from' to base64 */ |
|
474 |
- if (openvpn_base64_encode (sig, asn_len + hashlen, &in_b64) <= 0) |
|
475 |
- { |
|
476 |
- rv = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
477 |
- goto done; |
|
478 |
- } |
|
479 |
- |
|
480 |
- /* call MI for signature */ |
|
481 |
- if (management) |
|
482 |
- out_b64 = management_query_rsa_sig (management, in_b64); |
|
483 |
- if (!out_b64) |
|
484 |
- { |
|
485 |
- rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; |
|
486 |
- goto done; |
|
487 |
- } |
|
488 |
- |
|
489 |
- /* decode base64 signature to binary and verify length */ |
|
490 |
- if ( openvpn_base64_decode (out_b64, sig, ctx->signature_length) != |
|
491 |
- ctx->signature_length ) |
|
492 |
- { |
|
493 |
- rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; |
|
494 |
- goto done; |
|
495 |
- } |
|
496 |
- |
|
497 |
- rv = 0; |
|
498 |
- |
|
499 |
-done: |
|
500 |
- if (in_b64) |
|
501 |
- free (in_b64); |
|
502 |
- if (out_b64) |
|
503 |
- free (out_b64); |
|
504 |
- return rv; |
|
505 |
-} |
|
506 |
- |
|
507 |
-static inline size_t external_key_len(void *vctx) |
|
508 |
-{ |
|
509 |
- struct external_context * const ctx = vctx; |
|
510 |
- |
|
511 |
- return ctx->signature_length; |
|
512 |
-} |
|
513 |
- |
|
514 |
-int |
|
515 |
-tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, |
|
516 |
- const char *cert_file, const char *cert_file_inline) |
|
517 |
-{ |
|
518 |
- ASSERT(NULL != ctx); |
|
519 |
- |
|
520 |
- tls_ctx_load_cert_file(ctx, cert_file, cert_file_inline); |
|
521 |
- |
|
522 |
- if (ctx->crt_chain == NULL) |
|
523 |
- return 0; |
|
524 |
- |
|
525 |
- ALLOC_OBJ_CLEAR (ctx->external_key, struct external_context); |
|
526 |
- ctx->external_key->signature_length = mbedtls_pk_get_len (&ctx->crt_chain->pk); |
|
527 |
- |
|
528 |
- ALLOC_OBJ_CLEAR (ctx->priv_key, mbedtls_pk_context); |
|
529 |
- if (!mbed_ok (mbedtls_pk_setup_rsa_alt (ctx->priv_key, ctx->external_key, |
|
530 |
- NULL, external_pkcs1_sign, external_key_len))) |
|
531 |
- return 0; |
|
532 |
- |
|
533 |
- return 1; |
|
534 |
-} |
|
535 |
-#endif |
|
536 |
- |
|
537 |
-void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, |
|
538 |
- const char *ca_inline, const char *ca_path, bool tls_server |
|
539 |
- ) |
|
540 |
-{ |
|
541 |
- if (ca_path) |
|
542 |
- msg(M_FATAL, "ERROR: mbed TLS cannot handle the capath directive"); |
|
543 |
- |
|
544 |
- if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline) |
|
545 |
- { |
|
546 |
- if (!mbed_ok (mbedtls_x509_crt_parse (ctx->ca_chain, |
|
547 |
- (const unsigned char *) ca_inline, strlen(ca_inline)+1))) |
|
548 |
- msg (M_FATAL, "Cannot load inline CA certificates"); |
|
549 |
- } |
|
550 |
- else |
|
551 |
- { |
|
552 |
- /* Load CA file for verifying peer supplied certificate */ |
|
553 |
- if (!mbed_ok (mbedtls_x509_crt_parse_file (ctx->ca_chain, ca_file))) |
|
554 |
- msg (M_FATAL, "Cannot load CA certificate file %s", ca_file); |
|
555 |
- } |
|
556 |
-} |
|
557 |
- |
|
558 |
-void |
|
559 |
-tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file, |
|
560 |
- const char *extra_certs_inline |
|
561 |
- ) |
|
562 |
-{ |
|
563 |
- ASSERT(NULL != ctx); |
|
564 |
- |
|
565 |
- if (!ctx->crt_chain) |
|
566 |
- { |
|
567 |
- ALLOC_OBJ_CLEAR (ctx->crt_chain, mbedtls_x509_crt); |
|
568 |
- } |
|
569 |
- |
|
570 |
- if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline) |
|
571 |
- { |
|
572 |
- if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain, |
|
573 |
- (const unsigned char *) extra_certs_inline, |
|
574 |
- strlen(extra_certs_inline)+1))) |
|
575 |
- msg (M_FATAL, "Cannot load inline extra-certs file"); |
|
576 |
- } |
|
577 |
- else |
|
578 |
- { |
|
579 |
- if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, extra_certs_file))) |
|
580 |
- msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file); |
|
581 |
- } |
|
582 |
-} |
|
583 |
- |
|
584 |
-/* ************************************** |
|
585 |
- * |
|
586 |
- * Key-state specific functions |
|
587 |
- * |
|
588 |
- ***************************************/ |
|
589 |
- |
|
590 |
-/* |
|
591 |
- * "Endless buffer" |
|
592 |
- */ |
|
593 |
- |
|
594 |
-static inline void buf_free_entry(buffer_entry *entry) |
|
595 |
-{ |
|
596 |
- if (NULL != entry) |
|
597 |
- { |
|
598 |
- free(entry->data); |
|
599 |
- free(entry); |
|
600 |
- } |
|
601 |
-} |
|
602 |
- |
|
603 |
-static void buf_free_entries(endless_buffer *buf) |
|
604 |
-{ |
|
605 |
- while(buf->first_block) |
|
606 |
- { |
|
607 |
- buffer_entry *cur_block = buf->first_block; |
|
608 |
- buf->first_block = cur_block->next_block; |
|
609 |
- buf_free_entry(cur_block); |
|
610 |
- } |
|
611 |
- buf->last_block = NULL; |
|
612 |
-} |
|
613 |
- |
|
614 |
-static int endless_buf_read( endless_buffer *in, unsigned char * out, size_t out_len ) |
|
615 |
-{ |
|
616 |
- size_t read_len = 0; |
|
617 |
- |
|
618 |
- if (in->first_block == NULL) |
|
619 |
- return MBEDTLS_ERR_SSL_WANT_READ; |
|
620 |
- |
|
621 |
- while (in->first_block != NULL && read_len < out_len) |
|
622 |
- { |
|
623 |
- int block_len = in->first_block->length - in->data_start; |
|
624 |
- if (block_len <= out_len - read_len) |
|
625 |
- { |
|
626 |
- buffer_entry *cur_entry = in->first_block; |
|
627 |
- memcpy(out + read_len, cur_entry->data + in->data_start, |
|
628 |
- block_len); |
|
629 |
- |
|
630 |
- read_len += block_len; |
|
631 |
- |
|
632 |
- in->first_block = cur_entry->next_block; |
|
633 |
- in->data_start = 0; |
|
634 |
- |
|
635 |
- if (in->first_block == NULL) |
|
636 |
- in->last_block = NULL; |
|
637 |
- |
|
638 |
- buf_free_entry(cur_entry); |
|
639 |
- } |
|
640 |
- else |
|
641 |
- { |
|
642 |
- memcpy(out + read_len, in->first_block->data + in->data_start, |
|
643 |
- out_len - read_len); |
|
644 |
- in->data_start += out_len - read_len; |
|
645 |
- read_len = out_len; |
|
646 |
- } |
|
647 |
- } |
|
648 |
- |
|
649 |
- return read_len; |
|
650 |
-} |
|
651 |
- |
|
652 |
-static int endless_buf_write( endless_buffer *out, const unsigned char *in, size_t len ) |
|
653 |
-{ |
|
654 |
- buffer_entry *new_block = malloc(sizeof(buffer_entry)); |
|
655 |
- if (NULL == new_block) |
|
656 |
- return MBEDTLS_ERR_NET_SEND_FAILED; |
|
657 |
- |
|
658 |
- new_block->data = malloc(len); |
|
659 |
- if (NULL == new_block->data) |
|
660 |
- { |
|
661 |
- free(new_block); |
|
662 |
- return MBEDTLS_ERR_NET_SEND_FAILED; |
|
663 |
- } |
|
664 |
- |
|
665 |
- new_block->length = len; |
|
666 |
- new_block->next_block = NULL; |
|
667 |
- |
|
668 |
- memcpy(new_block->data, in, len); |
|
669 |
- |
|
670 |
- if (NULL == out->first_block) |
|
671 |
- out->first_block = new_block; |
|
672 |
- |
|
673 |
- if (NULL != out->last_block) |
|
674 |
- out->last_block->next_block = new_block; |
|
675 |
- |
|
676 |
- out->last_block = new_block; |
|
677 |
- |
|
678 |
- return len; |
|
679 |
-} |
|
680 |
- |
|
681 |
-static int ssl_bio_read( void *ctx, unsigned char *out, size_t out_len) |
|
682 |
-{ |
|
683 |
- bio_ctx *my_ctx = (bio_ctx *) ctx; |
|
684 |
- return endless_buf_read (&my_ctx->in, out, out_len); |
|
685 |
-} |
|
686 |
- |
|
687 |
-static int ssl_bio_write( void *ctx, const unsigned char *in, size_t in_len) |
|
688 |
-{ |
|
689 |
- bio_ctx *my_ctx = (bio_ctx *) ctx; |
|
690 |
- return endless_buf_write (&my_ctx->out, in, in_len); |
|
691 |
-} |
|
692 |
- |
|
693 |
-static void my_debug( void *ctx, int level, const char *file, int line, |
|
694 |
- const char *str ) |
|
695 |
-{ |
|
696 |
- int my_loglevel = (level < 3) ? D_TLS_DEBUG_MED : D_TLS_DEBUG; |
|
697 |
- msg (my_loglevel, "mbed TLS msg (%s:%d): %s", file, line, str); |
|
698 |
-} |
|
699 |
- |
|
700 |
-/* |
|
701 |
- * Further personalise the RNG using a hash of the public key |
|
702 |
- */ |
|
703 |
-void tls_ctx_personalise_random(struct tls_root_ctx *ctx) |
|
704 |
-{ |
|
705 |
- static char old_sha256_hash[32] = {0}; |
|
706 |
- unsigned char sha256_hash[32] = {0}; |
|
707 |
- mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get(); |
|
708 |
- |
|
709 |
- if (NULL != ctx->crt_chain) |
|
710 |
- { |
|
711 |
- mbedtls_x509_crt *cert = ctx->crt_chain; |
|
712 |
- |
|
713 |
- mbedtls_sha256(cert->tbs.p, cert->tbs.len, sha256_hash, false); |
|
714 |
- if ( 0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash))) |
|
715 |
- { |
|
716 |
- mbedtls_ctr_drbg_update(cd_ctx, sha256_hash, 32); |
|
717 |
- memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash)); |
|
718 |
- } |
|
719 |
- } |
|
720 |
-} |
|
721 |
- |
|
722 |
-int |
|
723 |
-tls_version_max(void) |
|
724 |
-{ |
|
725 |
-#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_3) |
|
726 |
- return TLS_VER_1_2; |
|
727 |
-#elif defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_2) |
|
728 |
- return TLS_VER_1_1; |
|
729 |
-#else |
|
730 |
- return TLS_VER_1_0; |
|
731 |
-#endif |
|
732 |
-} |
|
733 |
- |
|
734 |
-/** |
|
735 |
- * Convert an OpenVPN tls-version variable to mbed TLS format (i.e. a major and |
|
736 |
- * minor ssl version number). |
|
737 |
- * |
|
738 |
- * @param tls_ver The tls-version variable to convert. |
|
739 |
- * @param major Returns the TLS major version in mbed TLS format. |
|
740 |
- * Must be a valid pointer. |
|
741 |
- * @param minor Returns the TLS minor version in mbed TLS format. |
|
742 |
- * Must be a valid pointer. |
|
743 |
- */ |
|
744 |
-static void tls_version_to_major_minor(int tls_ver, int *major, int *minor) { |
|
745 |
- ASSERT(major); |
|
746 |
- ASSERT(minor); |
|
747 |
- |
|
748 |
- switch (tls_ver) |
|
749 |
- { |
|
750 |
- case TLS_VER_1_0: |
|
751 |
- *major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
752 |
- *minor = MBEDTLS_SSL_MINOR_VERSION_1; |
|
753 |
- break; |
|
754 |
- case TLS_VER_1_1: |
|
755 |
- *major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
756 |
- *minor = MBEDTLS_SSL_MINOR_VERSION_2; |
|
757 |
- break; |
|
758 |
- case TLS_VER_1_2: |
|
759 |
- *major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
760 |
- *minor = MBEDTLS_SSL_MINOR_VERSION_3; |
|
761 |
- break; |
|
762 |
- default: |
|
763 |
- msg(M_FATAL, "%s: invalid TLS version %d", __func__, tls_ver); |
|
764 |
- break; |
|
765 |
- } |
|
766 |
-} |
|
767 |
- |
|
768 |
-void key_state_ssl_init(struct key_state_ssl *ks_ssl, |
|
769 |
- const struct tls_root_ctx *ssl_ctx, bool is_server, struct tls_session *session) |
|
770 |
-{ |
|
771 |
- ASSERT(NULL != ssl_ctx); |
|
772 |
- ASSERT(ks_ssl); |
|
773 |
- CLEAR(*ks_ssl); |
|
774 |
- |
|
775 |
- /* Initialise SSL config */ |
|
776 |
- mbedtls_ssl_config_init(&ks_ssl->ssl_config); |
|
777 |
- mbedtls_ssl_config_defaults(&ks_ssl->ssl_config, ssl_ctx->endpoint, |
|
778 |
- MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); |
|
779 |
- mbedtls_debug_set_threshold(3); |
|
780 |
- mbedtls_ssl_conf_dbg (&ks_ssl->ssl_config, my_debug, NULL); |
|
781 |
- mbedtls_ssl_conf_rng (&ks_ssl->ssl_config, mbedtls_ctr_drbg_random, |
|
782 |
- rand_ctx_get()); |
|
783 |
- |
|
784 |
- if (ssl_ctx->allowed_ciphers) |
|
785 |
- mbedtls_ssl_conf_ciphersuites (&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers); |
|
786 |
- |
|
787 |
- /* Disable record splitting (for now). OpenVPN assumes records are sent |
|
788 |
- * unfragmented, and changing that will require thorough review and |
|
789 |
- * testing. Since OpenVPN is not susceptible to BEAST, we can just |
|
790 |
- * disable record splitting as a quick fix. */ |
|
791 |
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
|
792 |
- mbedtls_ssl_conf_cbc_record_splitting (&ks_ssl->ssl_config, |
|
793 |
- MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED); |
|
794 |
-#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ |
|
795 |
- |
|
796 |
- /* Initialise authentication information */ |
|
797 |
- if (is_server) |
|
798 |
- mbed_ok (mbedtls_ssl_conf_dh_param_ctx(&ks_ssl->ssl_config, |
|
799 |
- ssl_ctx->dhm_ctx)); |
|
800 |
- |
|
801 |
- mbed_ok (mbedtls_ssl_conf_own_cert(&ks_ssl->ssl_config, ssl_ctx->crt_chain, |
|
802 |
- ssl_ctx->priv_key)); |
|
803 |
- |
|
804 |
- /* Initialise SSL verification */ |
|
805 |
-#if P2MP_SERVER |
|
806 |
- if (session->opt->ssl_flags & SSLF_CLIENT_CERT_OPTIONAL) |
|
807 |
- { |
|
808 |
- mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL); |
|
809 |
- } |
|
810 |
- else if (!(session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)) |
|
811 |
-#endif |
|
812 |
- { |
|
813 |
- mbedtls_ssl_conf_authmode (&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_REQUIRED); |
|
814 |
- } |
|
815 |
- mbedtls_ssl_conf_verify (&ks_ssl->ssl_config, verify_callback, session); |
|
816 |
- |
|
817 |
- /* TODO: mbed TLS does not currently support sending the CA chain to the client */ |
|
818 |
- mbedtls_ssl_conf_ca_chain (&ks_ssl->ssl_config, ssl_ctx->ca_chain, NULL ); |
|
819 |
- |
|
820 |
- /* Initialize minimum TLS version */ |
|
821 |
- { |
|
822 |
- const int tls_version_min = |
|
823 |
- (session->opt->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & |
|
824 |
- SSLF_TLS_VERSION_MIN_MASK; |
|
825 |
- |
|
826 |
- /* default to TLS 1.0 */ |
|
827 |
- int major = MBEDTLS_SSL_MAJOR_VERSION_3; |
|
828 |
- int minor = MBEDTLS_SSL_MINOR_VERSION_1; |
|
829 |
- |
|
830 |
- if (tls_version_min > TLS_VER_UNSPEC) |
|
831 |
- tls_version_to_major_minor(tls_version_min, &major, &minor); |
|
832 |
- |
|
833 |
- mbedtls_ssl_conf_min_version(&ks_ssl->ssl_config, major, minor); |
|
834 |
- } |
|
835 |
- |
|
836 |
- /* Initialize maximum TLS version */ |
|
837 |
- { |
|
838 |
- const int tls_version_max = |
|
839 |
- (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & |
|
840 |
- SSLF_TLS_VERSION_MAX_MASK; |
|
841 |
- |
|
842 |
- if (tls_version_max > TLS_VER_UNSPEC) |
|
843 |
- { |
|
844 |
- int major, minor; |
|
845 |
- tls_version_to_major_minor(tls_version_max, &major, &minor); |
|
846 |
- mbedtls_ssl_conf_max_version(&ks_ssl->ssl_config, major, minor); |
|
847 |
- } |
|
848 |
- } |
|
849 |
- |
|
850 |
- /* Initialise SSL context */ |
|
851 |
- ALLOC_OBJ_CLEAR(ks_ssl->ctx, mbedtls_ssl_context); |
|
852 |
- mbedtls_ssl_init(ks_ssl->ctx); |
|
853 |
- mbedtls_ssl_setup(ks_ssl->ctx, &ks_ssl->ssl_config); |
|
854 |
- |
|
855 |
- /* Initialise BIOs */ |
|
856 |
- CLEAR (ks_ssl->bio_ctx); |
|
857 |
- mbedtls_ssl_set_bio (ks_ssl->ctx, &ks_ssl->bio_ctx, ssl_bio_write, |
|
858 |
- ssl_bio_read, NULL); |
|
859 |
-} |
|
860 |
- |
|
861 |
-void |
|
862 |
-key_state_ssl_free(struct key_state_ssl *ks_ssl) |
|
863 |
-{ |
|
864 |
- if (ks_ssl) { |
|
865 |
- if (ks_ssl->ctx) |
|
866 |
- { |
|
867 |
- mbedtls_ssl_free(ks_ssl->ctx); |
|
868 |
- free(ks_ssl->ctx); |
|
869 |
- } |
|
870 |
- mbedtls_ssl_config_free(&ks_ssl->ssl_config); |
|
871 |
- buf_free_entries(&ks_ssl->bio_ctx.in); |
|
872 |
- buf_free_entries(&ks_ssl->bio_ctx.out); |
|
873 |
- CLEAR(*ks_ssl); |
|
874 |
- } |
|
875 |
-} |
|
876 |
- |
|
877 |
-int |
|
878 |
-key_state_write_plaintext (struct key_state_ssl *ks, struct buffer *buf) |
|
879 |
-{ |
|
880 |
- int retval = 0; |
|
881 |
- |
|
882 |
- ASSERT (buf); |
|
883 |
- |
|
884 |
- retval = key_state_write_plaintext_const(ks, BPTR(buf), BLEN(buf)); |
|
885 |
- |
|
886 |
- if (1 == retval) |
|
887 |
- { |
|
888 |
- memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */ |
|
889 |
- buf->len = 0; |
|
890 |
- } |
|
891 |
- |
|
892 |
- return retval; |
|
893 |
-} |
|
894 |
- |
|
895 |
-int |
|
896 |
-key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data, int len) |
|
897 |
-{ |
|
898 |
- int retval = 0; |
|
899 |
- perf_push (PERF_BIO_WRITE_PLAINTEXT); |
|
900 |
- |
|
901 |
- ASSERT (NULL != ks); |
|
902 |
- ASSERT (len >= 0); |
|
903 |
- |
|
904 |
- if (0 == len) |
|
905 |
- { |
|
906 |
- perf_pop (); |
|
907 |
- return 0; |
|
908 |
- } |
|
909 |
- |
|
910 |
- ASSERT (data); |
|
911 |
- |
|
912 |
- retval = mbedtls_ssl_write(ks->ctx, data, len); |
|
913 |
- |
|
914 |
- if (retval < 0) |
|
915 |
- { |
|
916 |
- perf_pop (); |
|
917 |
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
918 |
- return 0; |
|
919 |
- mbed_log_err (D_TLS_ERRORS, retval, |
|
920 |
- "TLS ERROR: write tls_write_plaintext_const error"); |
|
921 |
- return -1; |
|
922 |
- } |
|
923 |
- |
|
924 |
- if (retval != len) |
|
925 |
- { |
|
926 |
- msg (D_TLS_ERRORS, |
|
927 |
- "TLS ERROR: write tls_write_plaintext_const incomplete %d/%d", |
|
928 |
- retval, len); |
|
929 |
- perf_pop (); |
|
930 |
- return -1; |
|
931 |
- } |
|
932 |
- |
|
933 |
- /* successful write */ |
|
934 |
- dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_plaintext_const %d bytes", retval); |
|
935 |
- |
|
936 |
- perf_pop (); |
|
937 |
- return 1; |
|
938 |
-} |
|
939 |
- |
|
940 |
-int |
|
941 |
-key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf, |
|
942 |
- int maxlen) |
|
943 |
-{ |
|
944 |
- int retval = 0; |
|
945 |
- int len = 0; |
|
946 |
- |
|
947 |
- perf_push (PERF_BIO_READ_CIPHERTEXT); |
|
948 |
- |
|
949 |
- ASSERT (NULL != ks); |
|
950 |
- ASSERT (buf); |
|
951 |
- ASSERT (buf->len >= 0); |
|
952 |
- |
|
953 |
- if (buf->len) |
|
954 |
- { |
|
955 |
- perf_pop (); |
|
956 |
- return 0; |
|
957 |
- } |
|
958 |
- |
|
959 |
- len = buf_forward_capacity (buf); |
|
960 |
- if (maxlen < len) |
|
961 |
- len = maxlen; |
|
962 |
- |
|
963 |
- retval = endless_buf_read(&ks->bio_ctx.out, BPTR(buf), len); |
|
964 |
- |
|
965 |
- /* Error during read, check for retry error */ |
|
966 |
- if (retval < 0) |
|
967 |
- { |
|
968 |
- perf_pop (); |
|
969 |
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
970 |
- return 0; |
|
971 |
- mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_ciphertext error"); |
|
972 |
- buf->len = 0; |
|
973 |
- return -1; |
|
974 |
- } |
|
975 |
- /* Nothing read, try again */ |
|
976 |
- if (0 == retval) |
|
977 |
- { |
|
978 |
- buf->len = 0; |
|
979 |
- perf_pop (); |
|
980 |
- return 0; |
|
981 |
- } |
|
982 |
- |
|
983 |
- /* successful read */ |
|
984 |
- dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_ciphertext %d bytes", retval); |
|
985 |
- buf->len = retval; |
|
986 |
- perf_pop (); |
|
987 |
- return 1; |
|
988 |
-} |
|
989 |
- |
|
990 |
-int |
|
991 |
-key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf) |
|
992 |
-{ |
|
993 |
- int retval = 0; |
|
994 |
- perf_push (PERF_BIO_WRITE_CIPHERTEXT); |
|
995 |
- |
|
996 |
- ASSERT (NULL != ks); |
|
997 |
- ASSERT (buf); |
|
998 |
- ASSERT (buf->len >= 0); |
|
999 |
- |
|
1000 |
- if (0 == buf->len) |
|
1001 |
- { |
|
1002 |
- perf_pop (); |
|
1003 |
- return 0; |
|
1004 |
- } |
|
1005 |
- |
|
1006 |
- retval = endless_buf_write(&ks->bio_ctx.in, BPTR(buf), buf->len); |
|
1007 |
- |
|
1008 |
- if (retval < 0) |
|
1009 |
- { |
|
1010 |
- perf_pop (); |
|
1011 |
- |
|
1012 |
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
1013 |
- return 0; |
|
1014 |
- mbed_log_err (D_TLS_ERRORS, retval, |
|
1015 |
- "TLS ERROR: write tls_write_ciphertext error"); |
|
1016 |
- return -1; |
|
1017 |
- } |
|
1018 |
- |
|
1019 |
- if (retval != buf->len) |
|
1020 |
- { |
|
1021 |
- msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext incomplete %d/%d", |
|
1022 |
- retval, buf->len); |
|
1023 |
- perf_pop (); |
|
1024 |
- return -1; |
|
1025 |
- } |
|
1026 |
- |
|
1027 |
- /* successful write */ |
|
1028 |
- dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_ciphertext %d bytes", retval); |
|
1029 |
- |
|
1030 |
- memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */ |
|
1031 |
- buf->len = 0; |
|
1032 |
- |
|
1033 |
- perf_pop (); |
|
1034 |
- return 1; |
|
1035 |
-} |
|
1036 |
- |
|
1037 |
-int |
|
1038 |
-key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf, |
|
1039 |
- int maxlen) |
|
1040 |
-{ |
|
1041 |
- int retval = 0; |
|
1042 |
- int len = 0; |
|
1043 |
- |
|
1044 |
- perf_push (PERF_BIO_READ_PLAINTEXT); |
|
1045 |
- |
|
1046 |
- ASSERT (NULL != ks); |
|
1047 |
- ASSERT (buf); |
|
1048 |
- ASSERT (buf->len >= 0); |
|
1049 |
- |
|
1050 |
- if (buf->len) |
|
1051 |
- { |
|
1052 |
- perf_pop (); |
|
1053 |
- return 0; |
|
1054 |
- } |
|
1055 |
- |
|
1056 |
- len = buf_forward_capacity (buf); |
|
1057 |
- if (maxlen < len) |
|
1058 |
- len = maxlen; |
|
1059 |
- |
|
1060 |
- retval = mbedtls_ssl_read(ks->ctx, BPTR(buf), len); |
|
1061 |
- |
|
1062 |
- /* Error during read, check for retry error */ |
|
1063 |
- if (retval < 0) |
|
1064 |
- { |
|
1065 |
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval) |
|
1066 |
- return 0; |
|
1067 |
- mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_plaintext error"); |
|
1068 |
- buf->len = 0; |
|
1069 |
- perf_pop (); |
|
1070 |
- return -1; |
|
1071 |
- } |
|
1072 |
- /* Nothing read, try again */ |
|
1073 |
- if (0 == retval) |
|
1074 |
- { |
|
1075 |
- buf->len = 0; |
|
1076 |
- perf_pop (); |
|
1077 |
- return 0; |
|
1078 |
- } |
|
1079 |
- |
|
1080 |
- /* successful read */ |
|
1081 |
- dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_plaintext %d bytes", retval); |
|
1082 |
- buf->len = retval; |
|
1083 |
- |
|
1084 |
- perf_pop (); |
|
1085 |
- return 1; |
|
1086 |
-} |
|
1087 |
- |
|
1088 |
-/* ************************************** |
|
1089 |
- * |
|
1090 |
- * Information functions |
|
1091 |
- * |
|
1092 |
- * Print information for the end user. |
|
1093 |
- * |
|
1094 |
- ***************************************/ |
|
1095 |
-void |
|
1096 |
-print_details (struct key_state_ssl * ks_ssl, const char *prefix) |
|
1097 |
-{ |
|
1098 |
- const mbedtls_x509_crt *cert; |
|
1099 |
- char s1[256]; |
|
1100 |
- char s2[256]; |
|
1101 |
- |
|
1102 |
- s1[0] = s2[0] = 0; |
|
1103 |
- openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s", |
|
1104 |
- prefix, |
|
1105 |
- mbedtls_ssl_get_version (ks_ssl->ctx), |
|
1106 |
- mbedtls_ssl_get_ciphersuite (ks_ssl->ctx)); |
|
1107 |
- |
|
1108 |
- cert = mbedtls_ssl_get_peer_cert (ks_ssl->ctx); |
|
1109 |
- if (cert != NULL) |
|
1110 |
- { |
|
1111 |
- openvpn_snprintf (s2, sizeof (s2), ", %zu bit key", |
|
1112 |
- mbedtls_pk_get_bitlen (&cert->pk)); |
|
1113 |
- } |
|
1114 |
- |
|
1115 |
- msg (D_HANDSHAKE, "%s%s", s1, s2); |
|
1116 |
-} |
|
1117 |
- |
|
1118 |
-void |
|
1119 |
-show_available_tls_ciphers (const char *cipher_list) |
|
1120 |
-{ |
|
1121 |
- struct tls_root_ctx tls_ctx; |
|
1122 |
- const int *ciphers = mbedtls_ssl_list_ciphersuites (); |
|
1123 |
- |
|
1124 |
- tls_ctx_server_new(&tls_ctx); |
|
1125 |
- tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); |
|
1126 |
- |
|
1127 |
- if (tls_ctx.allowed_ciphers) |
|
1128 |
- ciphers = tls_ctx.allowed_ciphers; |
|
1129 |
- |
|
1130 |
-#ifndef ENABLE_SMALL |
|
1131 |
- printf ("Available TLS Ciphers,\n"); |
|
1132 |
- printf ("listed in order of preference:\n\n"); |
|
1133 |
-#endif |
|
1134 |
- |
|
1135 |
- while (*ciphers != 0) |
|
1136 |
- { |
|
1137 |
- printf ("%s\n", mbedtls_ssl_get_ciphersuite_name (*ciphers)); |
|
1138 |
- ciphers++; |
|
1139 |
- } |
|
1140 |
- printf ("\n" SHOW_TLS_CIPHER_LIST_WARNING); |
|
1141 |
- |
|
1142 |
- tls_ctx_free(&tls_ctx); |
|
1143 |
-} |
|
1144 |
- |
|
1145 |
-void |
|
1146 |
-show_available_curves (void) |
|
1147 |
-{ |
|
1148 |
- const mbedtls_ecp_curve_info *pcurve = mbedtls_ecp_curve_list (); |
|
1149 |
- |
|
1150 |
- if (NULL == pcurve) |
|
1151 |
- msg (M_FATAL, "Cannot retrieve curve list from mbed TLS"); |
|
1152 |
- |
|
1153 |
- /* Print curve list */ |
|
1154 |
- printf ("Available Elliptic curves, listed in order of preference:\n\n"); |
|
1155 |
- while (MBEDTLS_ECP_DP_NONE != pcurve->grp_id) |
|
1156 |
- { |
|
1157 |
- printf("%s\n", pcurve->name); |
|
1158 |
- pcurve++; |
|
1159 |
- } |
|
1160 |
-} |
|
1161 |
- |
|
1162 |
-void |
|
1163 |
-get_highest_preference_tls_cipher (char *buf, int size) |
|
1164 |
-{ |
|
1165 |
- const char *cipher_name; |
|
1166 |
- const int *ciphers = mbedtls_ssl_list_ciphersuites(); |
|
1167 |
- if (*ciphers == 0) |
|
1168 |
- msg (M_FATAL, "Cannot retrieve list of supported SSL ciphers."); |
|
1169 |
- |
|
1170 |
- cipher_name = mbedtls_ssl_get_ciphersuite_name(*ciphers); |
|
1171 |
- strncpynt (buf, cipher_name, size); |
|
1172 |
-} |
|
1173 |
- |
|
1174 |
-const char * |
|
1175 |
-get_ssl_library_version(void) |
|
1176 |
-{ |
|
1177 |
- static char mbedtls_version[30]; |
|
1178 |
- unsigned int pv = mbedtls_version_get_number(); |
|
1179 |
- sprintf( mbedtls_version, "mbed TLS %d.%d.%d", |
|
1180 |
- (pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff ); |
|
1181 |
- return mbedtls_version; |
|
1182 |
-} |
|
1183 |
- |
|
1184 |
-#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) */ |
1185 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,92 +0,0 @@ |
1 |
-/* |
|
2 |
- * OpenVPN -- An application to securely tunnel IP networks |
|
3 |
- * over a single TCP/UDP port, with support for SSL/TLS-based |
|
4 |
- * session authentication and key exchange, |
|
5 |
- * packet encryption, packet authentication, and |
|
6 |
- * packet compression. |
|
7 |
- * |
|
8 |
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
9 |
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
10 |
- * |
|
11 |
- * This program is free software; you can redistribute it and/or modify |
|
12 |
- * it under the terms of the GNU General Public License version 2 |
|
13 |
- * as published by the Free Software Foundation. |
|
14 |
- * |
|
15 |
- * This program is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
- * GNU General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU General Public License |
|
21 |
- * along with this program (see the file COPYING included with this |
|
22 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
23 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
- */ |
|
25 |
- |
|
26 |
-/** |
|
27 |
- * @file Control Channel mbed TLS Backend |
|
28 |
- */ |
|
29 |
- |
|
30 |
-#ifndef SSL_MBEDTLS_H_ |
|
31 |
-#define SSL_MBEDTLS_H_ |
|
32 |
- |
|
33 |
-#include "syshead.h" |
|
34 |
- |
|
35 |
-#include <mbedtls/ssl.h> |
|
36 |
-#include <mbedtls/x509_crt.h> |
|
37 |
- |
|
38 |
-#if defined(ENABLE_PKCS11) |
|
39 |
-#include <mbedtls/pkcs11.h> |
|
40 |
-#endif |
|
41 |
- |
|
42 |
-typedef struct _buffer_entry buffer_entry; |
|
43 |
- |
|
44 |
-struct _buffer_entry { |
|
45 |
- size_t length; |
|
46 |
- uint8_t *data; |
|
47 |
- buffer_entry *next_block; |
|
48 |
-}; |
|
49 |
- |
|
50 |
-typedef struct { |
|
51 |
- size_t data_start; |
|
52 |
- buffer_entry *first_block; |
|
53 |
- buffer_entry *last_block; |
|
54 |
-} endless_buffer; |
|
55 |
- |
|
56 |
-typedef struct { |
|
57 |
- endless_buffer in; |
|
58 |
- endless_buffer out; |
|
59 |
-} bio_ctx; |
|
60 |
- |
|
61 |
-/** |
|
62 |
- * Structure that wraps the TLS context. Contents differ depending on the |
|
63 |
- * SSL library used. |
|
64 |
- * |
|
65 |
- * Either \c priv_key_pkcs11 or \c priv_key must be filled in. |
|
66 |
- */ |
|
67 |
-struct tls_root_ctx { |
|
68 |
- bool initialised; /**< True if the context has been initialised */ |
|
69 |
- |
|
70 |
- int endpoint; /**< Whether or not this is a server or a client */ |
|
71 |
- |
|
72 |
- mbedtls_dhm_context *dhm_ctx; /**< Diffie-Helmann-Merkle context */ |
|
73 |
- mbedtls_x509_crt *crt_chain; /**< Local Certificate chain */ |
|
74 |
- mbedtls_x509_crt *ca_chain; /**< CA chain for remote verification */ |
|
75 |
- mbedtls_pk_context *priv_key; /**< Local private key */ |
|
76 |
-#if defined(ENABLE_PKCS11) |
|
77 |
- mbedtls_pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */ |
|
78 |
-#endif |
|
79 |
-#ifdef MANAGMENT_EXTERNAL_KEY |
|
80 |
- struct external_context *external_key; /**< Management external key */ |
|
81 |
-#endif |
|
82 |
- int * allowed_ciphers; /**< List of allowed ciphers for this connection */ |
|
83 |
-}; |
|
84 |
- |
|
85 |
-struct key_state_ssl { |
|
86 |
- mbedtls_ssl_config ssl_config; /**< mbedTLS global ssl config */ |
|
87 |
- mbedtls_ssl_context *ctx; /**< mbedTLS connection context */ |
|
88 |
- bio_ctx bio_ctx; |
|
89 |
-}; |
|
90 |
- |
|
91 |
- |
|
92 |
-#endif /* SSL_MBEDTLS_H_ */ |
48 | 48 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,508 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
9 |
+ * |
|
10 |
+ * This program is free software; you can redistribute it and/or modify |
|
11 |
+ * it under the terms of the GNU General Public License version 2 |
|
12 |
+ * as published by the Free Software Foundation. |
|
13 |
+ * |
|
14 |
+ * This program is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 |
+ * GNU General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU General Public License |
|
20 |
+ * along with this program (see the file COPYING included with this |
|
21 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
22 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
23 |
+ */ |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @file Control Channel Verification Module mbed TLS backend |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+#ifdef HAVE_CONFIG_H |
|
30 |
+#include "config.h" |
|
31 |
+#elif defined(_MSC_VER) |
|
32 |
+#include "config-msvc.h" |
|
33 |
+#endif |
|
34 |
+ |
|
35 |
+#include "syshead.h" |
|
36 |
+ |
|
37 |
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
38 |
+ |
|
39 |
+#include "crypto_mbedtls.h" |
|
40 |
+#include "ssl_verify.h" |
|
41 |
+#include <mbedtls/asn1.h> |
|
42 |
+#include <mbedtls/error.h> |
|
43 |
+#include <mbedtls/bignum.h> |
|
44 |
+#include <mbedtls/oid.h> |
|
45 |
+#include <mbedtls/sha1.h> |
|
46 |
+ |
|
47 |
+#define MAX_SUBJECT_LENGTH 256 |
|
48 |
+ |
|
49 |
+int |
|
50 |
+verify_callback (void *session_obj, mbedtls_x509_crt *cert, int cert_depth, |
|
51 |
+ uint32_t *flags) |
|
52 |
+{ |
|
53 |
+ struct tls_session *session = (struct tls_session *) session_obj; |
|
54 |
+ struct gc_arena gc = gc_new(); |
|
55 |
+ |
|
56 |
+ ASSERT (cert); |
|
57 |
+ ASSERT (session); |
|
58 |
+ |
|
59 |
+ session->verified = false; |
|
60 |
+ |
|
61 |
+ /* Remember certificate hash */ |
|
62 |
+ cert_hash_remember (session, cert_depth, x509_get_sha1_hash(cert, &gc)); |
|
63 |
+ |
|
64 |
+ /* did peer present cert which was signed by our root cert? */ |
|
65 |
+ if (*flags != 0) |
|
66 |
+ { |
|
67 |
+ char *subject = x509_get_subject(cert, &gc); |
|
68 |
+ |
|
69 |
+ if (subject) |
|
70 |
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, %s", cert_depth, *flags, subject); |
|
71 |
+ else |
|
72 |
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, could not extract X509 " |
|
73 |
+ "subject string from certificate", *flags, cert_depth); |
|
74 |
+ |
|
75 |
+ /* Leave flags set to non-zero to indicate that the cert is not ok */ |
|
76 |
+ } |
|
77 |
+ else if (SUCCESS != verify_cert(session, cert, cert_depth)) |
|
78 |
+ { |
|
79 |
+ *flags |= MBEDTLS_X509_BADCERT_OTHER; |
|
80 |
+ } |
|
81 |
+ |
|
82 |
+ gc_free(&gc); |
|
83 |
+ |
|
84 |
+ /* |
|
85 |
+ * PolarSSL/mbed TLS-1.2.0+ expects 0 on anything except fatal errors. |
|
86 |
+ */ |
|
87 |
+ return 0; |
|
88 |
+} |
|
89 |
+ |
|
90 |
+#ifdef ENABLE_X509ALTUSERNAME |
|
91 |
+# warning "X509 alt user name not yet supported for mbed TLS" |
|
92 |
+#endif |
|
93 |
+ |
|
94 |
+result_t |
|
95 |
+backend_x509_get_username (char *cn, int cn_len, |
|
96 |
+ char *x509_username_field, mbedtls_x509_crt *cert) |
|
97 |
+{ |
|
98 |
+ mbedtls_x509_name *name; |
|
99 |
+ |
|
100 |
+ ASSERT( cn != NULL ); |
|
101 |
+ |
|
102 |
+ name = &cert->subject; |
|
103 |
+ |
|
104 |
+ /* Find common name */ |
|
105 |
+ while( name != NULL ) |
|
106 |
+ { |
|
107 |
+ if (0 == memcmp (name->oid.p, MBEDTLS_OID_AT_CN, |
|
108 |
+ MBEDTLS_OID_SIZE (MBEDTLS_OID_AT_CN))) |
|
109 |
+ break; |
|
110 |
+ |
|
111 |
+ name = name->next; |
|
112 |
+ } |
|
113 |
+ |
|
114 |
+ /* Not found, return an error if this is the peer's certificate */ |
|
115 |
+ if( name == NULL ) |
|
116 |
+ return FAILURE; |
|
117 |
+ |
|
118 |
+ /* Found, extract CN */ |
|
119 |
+ if (cn_len > name->val.len) |
|
120 |
+ { |
|
121 |
+ memcpy( cn, name->val.p, name->val.len ); |
|
122 |
+ cn[name->val.len] = '\0'; |
|
123 |
+ } |
|
124 |
+ else |
|
125 |
+ { |
|
126 |
+ memcpy( cn, name->val.p, cn_len); |
|
127 |
+ cn[cn_len-1] = '\0'; |
|
128 |
+ } |
|
129 |
+ |
|
130 |
+ return SUCCESS; |
|
131 |
+} |
|
132 |
+ |
|
133 |
+char * |
|
134 |
+backend_x509_get_serial (mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
135 |
+{ |
|
136 |
+ char *buf = NULL; |
|
137 |
+ size_t buflen = 0; |
|
138 |
+ mbedtls_mpi serial_mpi = { 0 }; |
|
139 |
+ |
|
140 |
+ /* Transform asn1 integer serial into mbed TLS MPI */ |
|
141 |
+ mbedtls_mpi_init(&serial_mpi); |
|
142 |
+ if (!mbed_ok(mbedtls_mpi_read_binary(&serial_mpi, cert->serial.p, |
|
143 |
+ cert->serial.len))) |
|
144 |
+ { |
|
145 |
+ msg(M_WARN, "Failed to retrieve serial from certificate."); |
|
146 |
+ return NULL; |
|
147 |
+ } |
|
148 |
+ |
|
149 |
+ /* Determine decimal representation length, allocate buffer */ |
|
150 |
+ mbedtls_mpi_write_string(&serial_mpi, 10, NULL, 0, &buflen); |
|
151 |
+ buf = gc_malloc(buflen, true, gc); |
|
152 |
+ |
|
153 |
+ /* Write MPI serial as decimal string into buffer */ |
|
154 |
+ if (!mbed_ok(mbedtls_mpi_write_string(&serial_mpi, 10, buf, buflen, &buflen))) |
|
155 |
+ { |
|
156 |
+ msg(M_WARN, "Failed to write serial to string."); |
|
157 |
+ return NULL; |
|
158 |
+ } |
|
159 |
+ |
|
160 |
+ return buf; |
|
161 |
+} |
|
162 |
+ |
|
163 |
+char * |
|
164 |
+backend_x509_get_serial_hex (mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
165 |
+{ |
|
166 |
+ char *buf = NULL; |
|
167 |
+ size_t len = cert->serial.len * 3 + 1; |
|
168 |
+ |
|
169 |
+ buf = gc_malloc(len, true, gc); |
|
170 |
+ |
|
171 |
+ if(mbedtls_x509_serial_gets(buf, len-1, &cert->serial) < 0) |
|
172 |
+ buf = NULL; |
|
173 |
+ |
|
174 |
+ return buf; |
|
175 |
+} |
|
176 |
+ |
|
177 |
+unsigned char * |
|
178 |
+x509_get_sha1_hash (mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
179 |
+{ |
|
180 |
+ unsigned char *sha1_hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc); |
|
181 |
+ mbedtls_sha1(cert->raw.p, cert->tbs.len, sha1_hash); |
|
182 |
+ return sha1_hash; |
|
183 |
+} |
|
184 |
+ |
|
185 |
+char * |
|
186 |
+x509_get_subject(mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
187 |
+{ |
|
188 |
+ char tmp_subject[MAX_SUBJECT_LENGTH] = {0}; |
|
189 |
+ char *subject = NULL; |
|
190 |
+ |
|
191 |
+ int ret = 0; |
|
192 |
+ |
|
193 |
+ ret = mbedtls_x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject ); |
|
194 |
+ if (ret > 0) |
|
195 |
+ { |
|
196 |
+ /* Allocate the required space for the subject */ |
|
197 |
+ subject = string_alloc(tmp_subject, gc); |
|
198 |
+ } |
|
199 |
+ |
|
200 |
+ return subject; |
|
201 |
+} |
|
202 |
+ |
|
203 |
+static void |
|
204 |
+do_setenv_x509 (struct env_set *es, const char *name, char *value, int depth) |
|
205 |
+{ |
|
206 |
+ char *name_expand; |
|
207 |
+ size_t name_expand_size; |
|
208 |
+ |
|
209 |
+ string_mod (value, CC_ANY, CC_CRLF, '?'); |
|
210 |
+ msg (D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth); |
|
211 |
+ name_expand_size = 64 + strlen (name); |
|
212 |
+ name_expand = (char *) malloc (name_expand_size); |
|
213 |
+ check_malloc_return (name_expand); |
|
214 |
+ openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", depth, name); |
|
215 |
+ setenv_str (es, name_expand, value); |
|
216 |
+ free (name_expand); |
|
217 |
+} |
|
218 |
+ |
|
219 |
+static char * |
|
220 |
+asn1_buf_to_c_string(const mbedtls_asn1_buf *orig, struct gc_arena *gc) |
|
221 |
+{ |
|
222 |
+ size_t i; |
|
223 |
+ char *val; |
|
224 |
+ |
|
225 |
+ for (i = 0; i < orig->len; ++i) |
|
226 |
+ if (orig->p[i] == '\0') |
|
227 |
+ return "ERROR: embedded null value"; |
|
228 |
+ val = gc_malloc(orig->len+1, false, gc); |
|
229 |
+ memcpy(val, orig->p, orig->len); |
|
230 |
+ val[orig->len] = '\0'; |
|
231 |
+ return val; |
|
232 |
+} |
|
233 |
+ |
|
234 |
+static void |
|
235 |
+do_setenv_name(struct env_set *es, const struct x509_track *xt, |
|
236 |
+ const mbedtls_x509_crt *cert, int depth, struct gc_arena *gc) |
|
237 |
+{ |
|
238 |
+ const mbedtls_x509_name *xn; |
|
239 |
+ for (xn = &cert->subject; xn != NULL; xn = xn->next) |
|
240 |
+ { |
|
241 |
+ const char *xn_short_name = NULL; |
|
242 |
+ if (0 == mbedtls_oid_get_attr_short_name (&xn->oid, &xn_short_name) && |
|
243 |
+ 0 == strcmp (xt->name, xn_short_name)) |
|
244 |
+ { |
|
245 |
+ char *val_str = asn1_buf_to_c_string (&xn->val, gc); |
|
246 |
+ do_setenv_x509 (es, xt->name, val_str, depth); |
|
247 |
+ } |
|
248 |
+ } |
|
249 |
+} |
|
250 |
+ |
|
251 |
+void |
|
252 |
+x509_track_add (const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc) |
|
253 |
+{ |
|
254 |
+ struct x509_track *xt; |
|
255 |
+ ALLOC_OBJ_CLEAR_GC (xt, struct x509_track, gc); |
|
256 |
+ if (*name == '+') |
|
257 |
+ { |
|
258 |
+ xt->flags |= XT_FULL_CHAIN; |
|
259 |
+ ++name; |
|
260 |
+ } |
|
261 |
+ xt->name = name; |
|
262 |
+ xt->next = *ll_head; |
|
263 |
+ *ll_head = xt; |
|
264 |
+} |
|
265 |
+ |
|
266 |
+void |
|
267 |
+x509_setenv_track (const struct x509_track *xt, struct env_set *es, |
|
268 |
+ const int depth, mbedtls_x509_crt *cert) |
|
269 |
+{ |
|
270 |
+ struct gc_arena gc = gc_new(); |
|
271 |
+ while (xt) |
|
272 |
+ { |
|
273 |
+ if (depth == 0 || (xt->flags & XT_FULL_CHAIN)) |
|
274 |
+ { |
|
275 |
+ if (0 == strcmp(xt->name, "SHA1")) |
|
276 |
+ { |
|
277 |
+ /* SHA1 fingerprint is not part of X509 structure */ |
|
278 |
+ unsigned char *sha1_hash = x509_get_sha1_hash(cert, &gc); |
|
279 |
+ char *sha1_fingerprint = format_hex_ex(sha1_hash, SHA_DIGEST_LENGTH, 0, 1 | FHE_CAPS, ":", &gc); |
|
280 |
+ do_setenv_x509(es, xt->name, sha1_fingerprint, depth); |
|
281 |
+ } |
|
282 |
+ else |
|
283 |
+ { |
|
284 |
+ do_setenv_name(es, xt, cert, depth, &gc); |
|
285 |
+ } |
|
286 |
+ } |
|
287 |
+ xt = xt->next; |
|
288 |
+ } |
|
289 |
+ gc_free(&gc); |
|
290 |
+} |
|
291 |
+ |
|
292 |
+/* |
|
293 |
+ * Save X509 fields to environment, using the naming convention: |
|
294 |
+ * |
|
295 |
+ * X509_{cert_depth}_{name}={value} |
|
296 |
+ */ |
|
297 |
+void |
|
298 |
+x509_setenv (struct env_set *es, int cert_depth, mbedtls_x509_crt *cert) |
|
299 |
+{ |
|
300 |
+ int i; |
|
301 |
+ unsigned char c; |
|
302 |
+ const mbedtls_x509_name *name; |
|
303 |
+ char s[128]; |
|
304 |
+ |
|
305 |
+ name = &cert->subject; |
|
306 |
+ |
|
307 |
+ memset( s, 0, sizeof( s ) ); |
|
308 |
+ |
|
309 |
+ while( name != NULL ) |
|
310 |
+ { |
|
311 |
+ char name_expand[64+8]; |
|
312 |
+ const char *shortname; |
|
313 |
+ |
|
314 |
+ if( 0 == mbedtls_oid_get_attr_short_name(&name->oid, &shortname) ) |
|
315 |
+ { |
|
316 |
+ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s", |
|
317 |
+ cert_depth, shortname); |
|
318 |
+ } |
|
319 |
+ else |
|
320 |
+ { |
|
321 |
+ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?", |
|
322 |
+ cert_depth); |
|
323 |
+ } |
|
324 |
+ |
|
325 |
+ for( i = 0; i < name->val.len; i++ ) |
|
326 |
+ { |
|
327 |
+ if( i >= (int) sizeof( s ) - 1 ) |
|
328 |
+ break; |
|
329 |
+ |
|
330 |
+ c = name->val.p[i]; |
|
331 |
+ if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) |
|
332 |
+ s[i] = '?'; |
|
333 |
+ else s[i] = c; |
|
334 |
+ } |
|
335 |
+ s[i] = '\0'; |
|
336 |
+ |
|
337 |
+ /* Check both strings, set environment variable */ |
|
338 |
+ string_mod (name_expand, CC_PRINT, CC_CRLF, '_'); |
|
339 |
+ string_mod ((char*)s, CC_PRINT, CC_CRLF, '_'); |
|
340 |
+ setenv_str_incr (es, name_expand, (char*)s); |
|
341 |
+ |
|
342 |
+ name = name->next; |
|
343 |
+ } |
|
344 |
+} |
|
345 |
+ |
|
346 |
+result_t |
|
347 |
+x509_verify_ns_cert_type(const mbedtls_x509_crt *cert, const int usage) |
|
348 |
+{ |
|
349 |
+ if (usage == NS_CERT_CHECK_NONE) |
|
350 |
+ return SUCCESS; |
|
351 |
+ if (usage == NS_CERT_CHECK_CLIENT) |
|
352 |
+ return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) |
|
353 |
+ && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT)) ? |
|
354 |
+ SUCCESS : FAILURE; |
|
355 |
+ if (usage == NS_CERT_CHECK_SERVER) |
|
356 |
+ return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) |
|
357 |
+ && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER)) ? |
|
358 |
+ SUCCESS : FAILURE; |
|
359 |
+ |
|
360 |
+ return FAILURE; |
|
361 |
+} |
|
362 |
+ |
|
363 |
+result_t |
|
364 |
+x509_verify_cert_ku (mbedtls_x509_crt *cert, const unsigned * const expected_ku, |
|
365 |
+ int expected_len) |
|
366 |
+{ |
|
367 |
+ result_t fFound = FAILURE; |
|
368 |
+ |
|
369 |
+ if(!(cert->ext_types & MBEDTLS_X509_EXT_KEY_USAGE)) |
|
370 |
+ { |
|
371 |
+ msg (D_HANDSHAKE, "Certificate does not have key usage extension"); |
|
372 |
+ } |
|
373 |
+ else |
|
374 |
+ { |
|
375 |
+ int i; |
|
376 |
+ unsigned nku = cert->key_usage; |
|
377 |
+ |
|
378 |
+ msg (D_HANDSHAKE, "Validating certificate key usage"); |
|
379 |
+ for (i=0; SUCCESS != fFound && i<expected_len; i++) |
|
380 |
+ { |
|
381 |
+ if (expected_ku[i] != 0) |
|
382 |
+ { |
|
383 |
+ msg (D_HANDSHAKE, "++ Certificate has key usage %04x, expects " |
|
384 |
+ "%04x", nku, expected_ku[i]); |
|
385 |
+ |
|
386 |
+ if (nku == expected_ku[i]) |
|
387 |
+ { |
|
388 |
+ fFound = SUCCESS; |
|
389 |
+ } |
|
390 |
+ } |
|
391 |
+ } |
|
392 |
+ } |
|
393 |
+ return fFound; |
|
394 |
+} |
|
395 |
+ |
|
396 |
+result_t |
|
397 |
+x509_verify_cert_eku (mbedtls_x509_crt *cert, const char * const expected_oid) |
|
398 |
+{ |
|
399 |
+ result_t fFound = FAILURE; |
|
400 |
+ |
|
401 |
+ if (!(cert->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE)) |
|
402 |
+ { |
|
403 |
+ msg (D_HANDSHAKE, "Certificate does not have extended key usage extension"); |
|
404 |
+ } |
|
405 |
+ else |
|
406 |
+ { |
|
407 |
+ mbedtls_x509_sequence *oid_seq = &(cert->ext_key_usage); |
|
408 |
+ |
|
409 |
+ msg (D_HANDSHAKE, "Validating certificate extended key usage"); |
|
410 |
+ while (oid_seq != NULL) |
|
411 |
+ { |
|
412 |
+ mbedtls_x509_buf *oid = &oid_seq->buf; |
|
413 |
+ char oid_num_str[1024]; |
|
414 |
+ const char *oid_str; |
|
415 |
+ |
|
416 |
+ if (0 == mbedtls_oid_get_extended_key_usage( oid, &oid_str )) |
|
417 |
+ { |
|
418 |
+ msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", |
|
419 |
+ oid_str, expected_oid); |
|
420 |
+ if (!strcmp (expected_oid, oid_str)) |
|
421 |
+ { |
|
422 |
+ fFound = SUCCESS; |
|
423 |
+ break; |
|
424 |
+ } |
|
425 |
+ } |
|
426 |
+ |
|
427 |
+ if (0 < mbedtls_oid_get_numeric_string( oid_num_str, |
|
428 |
+ sizeof (oid_num_str), oid)) |
|
429 |
+ { |
|
430 |
+ msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", |
|
431 |
+ oid_num_str, expected_oid); |
|
432 |
+ if (!strcmp (expected_oid, oid_num_str)) |
|
433 |
+ { |
|
434 |
+ fFound = SUCCESS; |
|
435 |
+ break; |
|
436 |
+ } |
|
437 |
+ } |
|
438 |
+ oid_seq = oid_seq->next; |
|
439 |
+ } |
|
440 |
+ } |
|
441 |
+ |
|
442 |
+ return fFound; |
|
443 |
+} |
|
444 |
+ |
|
445 |
+result_t |
|
446 |
+x509_write_pem(FILE *peercert_file, mbedtls_x509_crt *peercert) |
|
447 |
+{ |
|
448 |
+ msg (M_WARN, "mbed TLS does not support writing peer certificate in PEM format"); |
|
449 |
+ return FAILURE; |
|
450 |
+} |
|
451 |
+ |
|
452 |
+/* |
|
453 |
+ * check peer cert against CRL |
|
454 |
+ */ |
|
455 |
+result_t |
|
456 |
+x509_verify_crl(const char *crl_file, const char *crl_inline, |
|
457 |
+ mbedtls_x509_crt *cert, const char *subject) |
|
458 |
+{ |
|
459 |
+ result_t retval = FAILURE; |
|
460 |
+ mbedtls_x509_crl crl = {0}; |
|
461 |
+ struct gc_arena gc = gc_new(); |
|
462 |
+ char *serial; |
|
463 |
+ |
|
464 |
+ if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline) |
|
465 |
+ { |
|
466 |
+ if (!mbed_ok(mbedtls_x509_crl_parse(&crl, |
|
467 |
+ (const unsigned char *)crl_inline, strlen(crl_inline)+1))) |
|
468 |
+ { |
|
469 |
+ msg (M_WARN, "CRL: cannot parse inline CRL"); |
|
470 |
+ goto end; |
|
471 |
+ } |
|
472 |
+ } |
|
473 |
+ else |
|
474 |
+ { |
|
475 |
+ if (!mbed_ok(mbedtls_x509_crl_parse_file(&crl, crl_file))) |
|
476 |
+ { |
|
477 |
+ msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file); |
|
478 |
+ goto end; |
|
479 |
+ } |
|
480 |
+ } |
|
481 |
+ |
|
482 |
+ if(cert->issuer_raw.len != crl.issuer_raw.len || |
|
483 |
+ memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0) |
|
484 |
+ { |
|
485 |
+ msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of " |
|
486 |
+ "certificate %s", crl_file, subject); |
|
487 |
+ retval = SUCCESS; |
|
488 |
+ goto end; |
|
489 |
+ } |
|
490 |
+ |
|
491 |
+ if (!mbed_ok(mbedtls_x509_crt_is_revoked(cert, &crl))) |
|
492 |
+ { |
|
493 |
+ serial = backend_x509_get_serial_hex(cert, &gc); |
|
494 |
+ msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE")); |
|
495 |
+ goto end; |
|
496 |
+ } |
|
497 |
+ |
|
498 |
+ retval = SUCCESS; |
|
499 |
+ msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); |
|
500 |
+ |
|
501 |
+end: |
|
502 |
+ gc_free(&gc); |
|
503 |
+ mbedtls_x509_crl_free(&crl); |
|
504 |
+ return retval; |
|
505 |
+} |
|
506 |
+ |
|
507 |
+#endif /* #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) */ |
0 | 508 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,78 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
9 |
+ * |
|
10 |
+ * This program is free software; you can redistribute it and/or modify |
|
11 |
+ * it under the terms of the GNU General Public License version 2 |
|
12 |
+ * as published by the Free Software Foundation. |
|
13 |
+ * |
|
14 |
+ * This program is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 |
+ * GNU General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU General Public License |
|
20 |
+ * along with this program (see the file COPYING included with this |
|
21 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
22 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
23 |
+ */ |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @file Control Channel Verification Module mbed TLS backend |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+#ifndef SSL_VERIFY_MBEDTLS_H_ |
|
30 |
+#define SSL_VERIFY_MBEDTLS_H_ |
|
31 |
+ |
|
32 |
+#include "syshead.h" |
|
33 |
+#include <mbedtls/x509_crt.h> |
|
34 |
+ |
|
35 |
+#ifndef __OPENVPN_X509_CERT_T_DECLARED |
|
36 |
+#define __OPENVPN_X509_CERT_T_DECLARED |
|
37 |
+typedef mbedtls_x509_crt openvpn_x509_cert_t; |
|
38 |
+#endif |
|
39 |
+ |
|
40 |
+/** @name Function for authenticating a new connection from a remote OpenVPN peer |
|
41 |
+ * @{ */ |
|
42 |
+ |
|
43 |
+/** |
|
44 |
+ * Verify that the remote OpenVPN peer's certificate allows setting up a |
|
45 |
+ * VPN tunnel. |
|
46 |
+ * @ingroup control_tls |
|
47 |
+ * |
|
48 |
+ * This callback function is called when a new TLS session is being setup to |
|
49 |
+ * determine whether the remote OpenVPN peer's certificate is allowed to |
|
50 |
+ * connect. It is called for once for every certificate in the chain. The |
|
51 |
+ * callback functionality is configured in the \c init_ssl() function, which |
|
52 |
+ * calls the mbed TLS library's \c ssl_set_verify_callback() function with \c |
|
53 |
+ * verify_callback() as its callback argument. |
|
54 |
+ * |
|
55 |
+ * It checks *flags and registers the certificate hash. If these steps succeed, |
|
56 |
+ * it calls the \c verify_cert() function, which performs OpenVPN-specific |
|
57 |
+ * verification. |
|
58 |
+ * |
|
59 |
+ * @param session_obj - The OpenVPN \c tls_session associated with this object, |
|
60 |
+ * as set during SSL session setup. |
|
61 |
+ * @param cert - The certificate used by mbed TLS. |
|
62 |
+ * @param cert_depth - The depth of the current certificate in the chain, with |
|
63 |
+ * 0 being the actual certificate. |
|
64 |
+ * @param flags - Whether the remote OpenVPN peer's certificate |
|
65 |
+ * passed verification. A value of 0 means it |
|
66 |
+ * verified successfully, any other value means it |
|
67 |
+ * failed. \c verify_callback() is considered to have |
|
68 |
+ * ok'ed this certificate if flags is 0 when it returns. |
|
69 |
+ * |
|
70 |
+ * @return The return value is 0 unless a fatal error occurred. |
|
71 |
+ */ |
|
72 |
+int verify_callback (void *session_obj, mbedtls_x509_crt *cert, int cert_depth, |
|
73 |
+ uint32_t *flags); |
|
74 |
+ |
|
75 |
+/** @} name Function for authenticating a new connection from a remote OpenVPN peer */ |
|
76 |
+ |
|
77 |
+#endif /* SSL_VERIFY_MBEDTLS_H_ */ |
0 | 78 |
deleted file mode 100644 |
... | ... |
@@ -1,508 +0,0 @@ |
1 |
-/* |
|
2 |
- * OpenVPN -- An application to securely tunnel IP networks |
|
3 |
- * over a single TCP/UDP port, with support for SSL/TLS-based |
|
4 |
- * session authentication and key exchange, |
|
5 |
- * packet encryption, packet authentication, and |
|
6 |
- * packet compression. |
|
7 |
- * |
|
8 |
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
9 |
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
10 |
- * |
|
11 |
- * This program is free software; you can redistribute it and/or modify |
|
12 |
- * it under the terms of the GNU General Public License version 2 |
|
13 |
- * as published by the Free Software Foundation. |
|
14 |
- * |
|
15 |
- * This program is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
- * GNU General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU General Public License |
|
21 |
- * along with this program (see the file COPYING included with this |
|
22 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
23 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
- */ |
|
25 |
- |
|
26 |
-/** |
|
27 |
- * @file Control Channel Verification Module mbed TLS backend |
|
28 |
- */ |
|
29 |
- |
|
30 |
-#ifdef HAVE_CONFIG_H |
|
31 |
-#include "config.h" |
|
32 |
-#elif defined(_MSC_VER) |
|
33 |
-#include "config-msvc.h" |
|
34 |
-#endif |
|
35 |
- |
|
36 |
-#include "syshead.h" |
|
37 |
- |
|
38 |
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) |
|
39 |
- |
|
40 |
-#include "crypto_polarssl.h" |
|
41 |
-#include "ssl_verify.h" |
|
42 |
-#include <mbedtls/asn1.h> |
|
43 |
-#include <mbedtls/error.h> |
|
44 |
-#include <mbedtls/bignum.h> |
|
45 |
-#include <mbedtls/oid.h> |
|
46 |
-#include <mbedtls/sha1.h> |
|
47 |
- |
|
48 |
-#define MAX_SUBJECT_LENGTH 256 |
|
49 |
- |
|
50 |
-int |
|
51 |
-verify_callback (void *session_obj, mbedtls_x509_crt *cert, int cert_depth, |
|
52 |
- uint32_t *flags) |
|
53 |
-{ |
|
54 |
- struct tls_session *session = (struct tls_session *) session_obj; |
|
55 |
- struct gc_arena gc = gc_new(); |
|
56 |
- |
|
57 |
- ASSERT (cert); |
|
58 |
- ASSERT (session); |
|
59 |
- |
|
60 |
- session->verified = false; |
|
61 |
- |
|
62 |
- /* Remember certificate hash */ |
|
63 |
- cert_hash_remember (session, cert_depth, x509_get_sha1_hash(cert, &gc)); |
|
64 |
- |
|
65 |
- /* did peer present cert which was signed by our root cert? */ |
|
66 |
- if (*flags != 0) |
|
67 |
- { |
|
68 |
- char *subject = x509_get_subject(cert, &gc); |
|
69 |
- |
|
70 |
- if (subject) |
|
71 |
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, %s", cert_depth, *flags, subject); |
|
72 |
- else |
|
73 |
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, could not extract X509 " |
|
74 |
- "subject string from certificate", *flags, cert_depth); |
|
75 |
- |
|
76 |
- /* Leave flags set to non-zero to indicate that the cert is not ok */ |
|
77 |
- } |
|
78 |
- else if (SUCCESS != verify_cert(session, cert, cert_depth)) |
|
79 |
- { |
|
80 |
- *flags |= MBEDTLS_X509_BADCERT_OTHER; |
|
81 |
- } |
|
82 |
- |
|
83 |
- gc_free(&gc); |
|
84 |
- |
|
85 |
- /* |
|
86 |
- * PolarSSL/mbed TLS-1.2.0+ expects 0 on anything except fatal errors. |
|
87 |
- */ |
|
88 |
- return 0; |
|
89 |
-} |
|
90 |
- |
|
91 |
-#ifdef ENABLE_X509ALTUSERNAME |
|
92 |
-# warning "X509 alt user name not yet supported for mbed TLS" |
|
93 |
-#endif |
|
94 |
- |
|
95 |
-result_t |
|
96 |
-backend_x509_get_username (char *cn, int cn_len, |
|
97 |
- char *x509_username_field, mbedtls_x509_crt *cert) |
|
98 |
-{ |
|
99 |
- mbedtls_x509_name *name; |
|
100 |
- |
|
101 |
- ASSERT( cn != NULL ); |
|
102 |
- |
|
103 |
- name = &cert->subject; |
|
104 |
- |
|
105 |
- /* Find common name */ |
|
106 |
- while( name != NULL ) |
|
107 |
- { |
|
108 |
- if (0 == memcmp (name->oid.p, MBEDTLS_OID_AT_CN, |
|
109 |
- MBEDTLS_OID_SIZE (MBEDTLS_OID_AT_CN))) |
|
110 |
- break; |
|
111 |
- |
|
112 |
- name = name->next; |
|
113 |
- } |
|
114 |
- |
|
115 |
- /* Not found, return an error if this is the peer's certificate */ |
|
116 |
- if( name == NULL ) |
|
117 |
- return FAILURE; |
|
118 |
- |
|
119 |
- /* Found, extract CN */ |
|
120 |
- if (cn_len > name->val.len) |
|
121 |
- { |
|
122 |
- memcpy( cn, name->val.p, name->val.len ); |
|
123 |
- cn[name->val.len] = '\0'; |
|
124 |
- } |
|
125 |
- else |
|
126 |
- { |
|
127 |
- memcpy( cn, name->val.p, cn_len); |
|
128 |
- cn[cn_len-1] = '\0'; |
|
129 |
- } |
|
130 |
- |
|
131 |
- return SUCCESS; |
|
132 |
-} |
|
133 |
- |
|
134 |
-char * |
|
135 |
-backend_x509_get_serial (mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
136 |
-{ |
|
137 |
- char *buf = NULL; |
|
138 |
- size_t buflen = 0; |
|
139 |
- mbedtls_mpi serial_mpi = { 0 }; |
|
140 |
- |
|
141 |
- /* Transform asn1 integer serial into mbed TLS MPI */ |
|
142 |
- mbedtls_mpi_init(&serial_mpi); |
|
143 |
- if (!mbed_ok(mbedtls_mpi_read_binary(&serial_mpi, cert->serial.p, |
|
144 |
- cert->serial.len))) |
|
145 |
- { |
|
146 |
- msg(M_WARN, "Failed to retrieve serial from certificate."); |
|
147 |
- return NULL; |
|
148 |
- } |
|
149 |
- |
|
150 |
- /* Determine decimal representation length, allocate buffer */ |
|
151 |
- mbedtls_mpi_write_string(&serial_mpi, 10, NULL, 0, &buflen); |
|
152 |
- buf = gc_malloc(buflen, true, gc); |
|
153 |
- |
|
154 |
- /* Write MPI serial as decimal string into buffer */ |
|
155 |
- if (!mbed_ok(mbedtls_mpi_write_string(&serial_mpi, 10, buf, buflen, &buflen))) |
|
156 |
- { |
|
157 |
- msg(M_WARN, "Failed to write serial to string."); |
|
158 |
- return NULL; |
|
159 |
- } |
|
160 |
- |
|
161 |
- return buf; |
|
162 |
-} |
|
163 |
- |
|
164 |
-char * |
|
165 |
-backend_x509_get_serial_hex (mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
166 |
-{ |
|
167 |
- char *buf = NULL; |
|
168 |
- size_t len = cert->serial.len * 3 + 1; |
|
169 |
- |
|
170 |
- buf = gc_malloc(len, true, gc); |
|
171 |
- |
|
172 |
- if(mbedtls_x509_serial_gets(buf, len-1, &cert->serial) < 0) |
|
173 |
- buf = NULL; |
|
174 |
- |
|
175 |
- return buf; |
|
176 |
-} |
|
177 |
- |
|
178 |
-unsigned char * |
|
179 |
-x509_get_sha1_hash (mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
180 |
-{ |
|
181 |
- unsigned char *sha1_hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc); |
|
182 |
- mbedtls_sha1(cert->raw.p, cert->tbs.len, sha1_hash); |
|
183 |
- return sha1_hash; |
|
184 |
-} |
|
185 |
- |
|
186 |
-char * |
|
187 |
-x509_get_subject(mbedtls_x509_crt *cert, struct gc_arena *gc) |
|
188 |
-{ |
|
189 |
- char tmp_subject[MAX_SUBJECT_LENGTH] = {0}; |
|
190 |
- char *subject = NULL; |
|
191 |
- |
|
192 |
- int ret = 0; |
|
193 |
- |
|
194 |
- ret = mbedtls_x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject ); |
|
195 |
- if (ret > 0) |
|
196 |
- { |
|
197 |
- /* Allocate the required space for the subject */ |
|
198 |
- subject = string_alloc(tmp_subject, gc); |
|
199 |
- } |
|
200 |
- |
|
201 |
- return subject; |
|
202 |
-} |
|
203 |
- |
|
204 |
-static void |
|
205 |
-do_setenv_x509 (struct env_set *es, const char *name, char *value, int depth) |
|
206 |
-{ |
|
207 |
- char *name_expand; |
|
208 |
- size_t name_expand_size; |
|
209 |
- |
|
210 |
- string_mod (value, CC_ANY, CC_CRLF, '?'); |
|
211 |
- msg (D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth); |
|
212 |
- name_expand_size = 64 + strlen (name); |
|
213 |
- name_expand = (char *) malloc (name_expand_size); |
|
214 |
- check_malloc_return (name_expand); |
|
215 |
- openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", depth, name); |
|
216 |
- setenv_str (es, name_expand, value); |
|
217 |
- free (name_expand); |
|
218 |
-} |
|
219 |
- |
|
220 |
-static char * |
|
221 |
-asn1_buf_to_c_string(const mbedtls_asn1_buf *orig, struct gc_arena *gc) |
|
222 |
-{ |
|
223 |
- size_t i; |
|
224 |
- char *val; |
|
225 |
- |
|
226 |
- for (i = 0; i < orig->len; ++i) |
|
227 |
- if (orig->p[i] == '\0') |
|
228 |
- return "ERROR: embedded null value"; |
|
229 |
- val = gc_malloc(orig->len+1, false, gc); |
|
230 |
- memcpy(val, orig->p, orig->len); |
|
231 |
- val[orig->len] = '\0'; |
|
232 |
- return val; |
|
233 |
-} |
|
234 |
- |
|
235 |
-static void |
|
236 |
-do_setenv_name(struct env_set *es, const struct x509_track *xt, |
|
237 |
- const mbedtls_x509_crt *cert, int depth, struct gc_arena *gc) |
|
238 |
-{ |
|
239 |
- const mbedtls_x509_name *xn; |
|
240 |
- for (xn = &cert->subject; xn != NULL; xn = xn->next) |
|
241 |
- { |
|
242 |
- const char *xn_short_name = NULL; |
|
243 |
- if (0 == mbedtls_oid_get_attr_short_name (&xn->oid, &xn_short_name) && |
|
244 |
- 0 == strcmp (xt->name, xn_short_name)) |
|
245 |
- { |
|
246 |
- char *val_str = asn1_buf_to_c_string (&xn->val, gc); |
|
247 |
- do_setenv_x509 (es, xt->name, val_str, depth); |
|
248 |
- } |
|
249 |
- } |
|
250 |
-} |
|
251 |
- |
|
252 |
-void |
|
253 |
-x509_track_add (const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc) |
|
254 |
-{ |
|
255 |
- struct x509_track *xt; |
|
256 |
- ALLOC_OBJ_CLEAR_GC (xt, struct x509_track, gc); |
|
257 |
- if (*name == '+') |
|
258 |
- { |
|
259 |
- xt->flags |= XT_FULL_CHAIN; |
|
260 |
- ++name; |
|
261 |
- } |
|
262 |
- xt->name = name; |
|
263 |
- xt->next = *ll_head; |
|
264 |
- *ll_head = xt; |
|
265 |
-} |
|
266 |
- |
|
267 |
-void |
|
268 |
-x509_setenv_track (const struct x509_track *xt, struct env_set *es, |
|
269 |
- const int depth, mbedtls_x509_crt *cert) |
|
270 |
-{ |
|
271 |
- struct gc_arena gc = gc_new(); |
|
272 |
- while (xt) |
|
273 |
- { |
|
274 |
- if (depth == 0 || (xt->flags & XT_FULL_CHAIN)) |
|
275 |
- { |
|
276 |
- if (0 == strcmp(xt->name, "SHA1")) |
|
277 |
- { |
|
278 |
- /* SHA1 fingerprint is not part of X509 structure */ |
|
279 |
- unsigned char *sha1_hash = x509_get_sha1_hash(cert, &gc); |
|
280 |
- char *sha1_fingerprint = format_hex_ex(sha1_hash, SHA_DIGEST_LENGTH, 0, 1 | FHE_CAPS, ":", &gc); |
|
281 |
- do_setenv_x509(es, xt->name, sha1_fingerprint, depth); |
|
282 |
- } |
|
283 |
- else |
|
284 |
- { |
|
285 |
- do_setenv_name(es, xt, cert, depth, &gc); |
|
286 |
- } |
|
287 |
- } |
|
288 |
- xt = xt->next; |
|
289 |
- } |
|
290 |
- gc_free(&gc); |
|
291 |
-} |
|
292 |
- |
|
293 |
-/* |
|
294 |
- * Save X509 fields to environment, using the naming convention: |
|
295 |
- * |
|
296 |
- * X509_{cert_depth}_{name}={value} |
|
297 |
- */ |
|
298 |
-void |
|
299 |
-x509_setenv (struct env_set *es, int cert_depth, mbedtls_x509_crt *cert) |
|
300 |
-{ |
|
301 |
- int i; |
|
302 |
- unsigned char c; |
|
303 |
- const mbedtls_x509_name *name; |
|
304 |
- char s[128]; |
|
305 |
- |
|
306 |
- name = &cert->subject; |
|
307 |
- |
|
308 |
- memset( s, 0, sizeof( s ) ); |
|
309 |
- |
|
310 |
- while( name != NULL ) |
|
311 |
- { |
|
312 |
- char name_expand[64+8]; |
|
313 |
- const char *shortname; |
|
314 |
- |
|
315 |
- if( 0 == mbedtls_oid_get_attr_short_name(&name->oid, &shortname) ) |
|
316 |
- { |
|
317 |
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s", |
|
318 |
- cert_depth, shortname); |
|
319 |
- } |
|
320 |
- else |
|
321 |
- { |
|
322 |
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?", |
|
323 |
- cert_depth); |
|
324 |
- } |
|
325 |
- |
|
326 |
- for( i = 0; i < name->val.len; i++ ) |
|
327 |
- { |
|
328 |
- if( i >= (int) sizeof( s ) - 1 ) |
|
329 |
- break; |
|
330 |
- |
|
331 |
- c = name->val.p[i]; |
|
332 |
- if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) |
|
333 |
- s[i] = '?'; |
|
334 |
- else s[i] = c; |
|
335 |
- } |
|
336 |
- s[i] = '\0'; |
|
337 |
- |
|
338 |
- /* Check both strings, set environment variable */ |
|
339 |
- string_mod (name_expand, CC_PRINT, CC_CRLF, '_'); |
|
340 |
- string_mod ((char*)s, CC_PRINT, CC_CRLF, '_'); |
|
341 |
- setenv_str_incr (es, name_expand, (char*)s); |
|
342 |
- |
|
343 |
- name = name->next; |
|
344 |
- } |
|
345 |
-} |
|
346 |
- |
|
347 |
-result_t |
|
348 |
-x509_verify_ns_cert_type(const mbedtls_x509_crt *cert, const int usage) |
|
349 |
-{ |
|
350 |
- if (usage == NS_CERT_CHECK_NONE) |
|
351 |
- return SUCCESS; |
|
352 |
- if (usage == NS_CERT_CHECK_CLIENT) |
|
353 |
- return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) |
|
354 |
- && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT)) ? |
|
355 |
- SUCCESS : FAILURE; |
|
356 |
- if (usage == NS_CERT_CHECK_SERVER) |
|
357 |
- return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) |
|
358 |
- && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER)) ? |
|
359 |
- SUCCESS : FAILURE; |
|
360 |
- |
|
361 |
- return FAILURE; |
|
362 |
-} |
|
363 |
- |
|
364 |
-result_t |
|
365 |
-x509_verify_cert_ku (mbedtls_x509_crt *cert, const unsigned * const expected_ku, |
|
366 |
- int expected_len) |
|
367 |
-{ |
|
368 |
- result_t fFound = FAILURE; |
|
369 |
- |
|
370 |
- if(!(cert->ext_types & MBEDTLS_X509_EXT_KEY_USAGE)) |
|
371 |
- { |
|
372 |
- msg (D_HANDSHAKE, "Certificate does not have key usage extension"); |
|
373 |
- } |
|
374 |
- else |
|
375 |
- { |
|
376 |
- int i; |
|
377 |
- unsigned nku = cert->key_usage; |
|
378 |
- |
|
379 |
- msg (D_HANDSHAKE, "Validating certificate key usage"); |
|
380 |
- for (i=0; SUCCESS != fFound && i<expected_len; i++) |
|
381 |
- { |
|
382 |
- if (expected_ku[i] != 0) |
|
383 |
- { |
|
384 |
- msg (D_HANDSHAKE, "++ Certificate has key usage %04x, expects " |
|
385 |
- "%04x", nku, expected_ku[i]); |
|
386 |
- |
|
387 |
- if (nku == expected_ku[i]) |
|
388 |
- { |
|
389 |
- fFound = SUCCESS; |
|
390 |
- } |
|
391 |
- } |
|
392 |
- } |
|
393 |
- } |
|
394 |
- return fFound; |
|
395 |
-} |
|
396 |
- |
|
397 |
-result_t |
|
398 |
-x509_verify_cert_eku (mbedtls_x509_crt *cert, const char * const expected_oid) |
|
399 |
-{ |
|
400 |
- result_t fFound = FAILURE; |
|
401 |
- |
|
402 |
- if (!(cert->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE)) |
|
403 |
- { |
|
404 |
- msg (D_HANDSHAKE, "Certificate does not have extended key usage extension"); |
|
405 |
- } |
|
406 |
- else |
|
407 |
- { |
|
408 |
- mbedtls_x509_sequence *oid_seq = &(cert->ext_key_usage); |
|
409 |
- |
|
410 |
- msg (D_HANDSHAKE, "Validating certificate extended key usage"); |
|
411 |
- while (oid_seq != NULL) |
|
412 |
- { |
|
413 |
- mbedtls_x509_buf *oid = &oid_seq->buf; |
|
414 |
- char oid_num_str[1024]; |
|
415 |
- const char *oid_str; |
|
416 |
- |
|
417 |
- if (0 == mbedtls_oid_get_extended_key_usage( oid, &oid_str )) |
|
418 |
- { |
|
419 |
- msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", |
|
420 |
- oid_str, expected_oid); |
|
421 |
- if (!strcmp (expected_oid, oid_str)) |
|
422 |
- { |
|
423 |
- fFound = SUCCESS; |
|
424 |
- break; |
|
425 |
- } |
|
426 |
- } |
|
427 |
- |
|
428 |
- if (0 < mbedtls_oid_get_numeric_string( oid_num_str, |
|
429 |
- sizeof (oid_num_str), oid)) |
|
430 |
- { |
|
431 |
- msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", |
|
432 |
- oid_num_str, expected_oid); |
|
433 |
- if (!strcmp (expected_oid, oid_num_str)) |
|
434 |
- { |
|
435 |
- fFound = SUCCESS; |
|
436 |
- break; |
|
437 |
- } |
|
438 |
- } |
|
439 |
- oid_seq = oid_seq->next; |
|
440 |
- } |
|
441 |
- } |
|
442 |
- |
|
443 |
- return fFound; |
|
444 |
-} |
|
445 |
- |
|
446 |
-result_t |
|
447 |
-x509_write_pem(FILE *peercert_file, mbedtls_x509_crt *peercert) |
|
448 |
-{ |
|
449 |
- msg (M_WARN, "mbed TLS does not support writing peer certificate in PEM format"); |
|
450 |
- return FAILURE; |
|
451 |
-} |
|
452 |
- |
|
453 |
-/* |
|
454 |
- * check peer cert against CRL |
|
455 |
- */ |
|
456 |
-result_t |
|
457 |
-x509_verify_crl(const char *crl_file, const char *crl_inline, |
|
458 |
- mbedtls_x509_crt *cert, const char *subject) |
|
459 |
-{ |
|
460 |
- result_t retval = FAILURE; |
|
461 |
- mbedtls_x509_crl crl = {0}; |
|
462 |
- struct gc_arena gc = gc_new(); |
|
463 |
- char *serial; |
|
464 |
- |
|
465 |
- if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline) |
|
466 |
- { |
|
467 |
- if (!mbed_ok(mbedtls_x509_crl_parse(&crl, |
|
468 |
- (const unsigned char *)crl_inline, strlen(crl_inline)+1))) |
|
469 |
- { |
|
470 |
- msg (M_WARN, "CRL: cannot parse inline CRL"); |
|
471 |
- goto end; |
|
472 |
- } |
|
473 |
- } |
|
474 |
- else |
|
475 |
- { |
|
476 |
- if (!mbed_ok(mbedtls_x509_crl_parse_file(&crl, crl_file))) |
|
477 |
- { |
|
478 |
- msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file); |
|
479 |
- goto end; |
|
480 |
- } |
|
481 |
- } |
|
482 |
- |
|
483 |
- if(cert->issuer_raw.len != crl.issuer_raw.len || |
|
484 |
- memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0) |
|
485 |
- { |
|
486 |
- msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of " |
|
487 |
- "certificate %s", crl_file, subject); |
|
488 |
- retval = SUCCESS; |
|
489 |
- goto end; |
|
490 |
- } |
|
491 |
- |
|
492 |
- if (!mbed_ok(mbedtls_x509_crt_is_revoked(cert, &crl))) |
|
493 |
- { |
|
494 |
- serial = backend_x509_get_serial_hex(cert, &gc); |
|
495 |
- msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE")); |
|
496 |
- goto end; |
|
497 |
- } |
|
498 |
- |
|
499 |
- retval = SUCCESS; |
|
500 |
- msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); |
|
501 |
- |
|
502 |
-end: |
|
503 |
- gc_free(&gc); |
|
504 |
- mbedtls_x509_crl_free(&crl); |
|
505 |
- return retval; |
|
506 |
-} |
|
507 |
- |
|
508 |
-#endif /* #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) */ |
509 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,78 +0,0 @@ |
1 |
-/* |
|
2 |
- * OpenVPN -- An application to securely tunnel IP networks |
|
3 |
- * over a single TCP/UDP port, with support for SSL/TLS-based |
|
4 |
- * session authentication and key exchange, |
|
5 |
- * packet encryption, packet authentication, and |
|
6 |
- * packet compression. |
|
7 |
- * |
|
8 |
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
9 |
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com> |
|
10 |
- * |
|
11 |
- * This program is free software; you can redistribute it and/or modify |
|
12 |
- * it under the terms of the GNU General Public License version 2 |
|
13 |
- * as published by the Free Software Foundation. |
|
14 |
- * |
|
15 |
- * This program is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
- * GNU General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU General Public License |
|
21 |
- * along with this program (see the file COPYING included with this |
|
22 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
23 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
- */ |
|
25 |
- |
|
26 |
-/** |
|
27 |
- * @file Control Channel Verification Module mbed TLS backend |
|
28 |
- */ |
|
29 |
- |
|
30 |
-#ifndef SSL_VERIFY_MBEDTLS_H_ |
|
31 |
-#define SSL_VERIFY_MBEDTLS_H_ |
|
32 |
- |
|
33 |
-#include "syshead.h" |
|
34 |
-#include <mbedtls/x509_crt.h> |
|
35 |
- |
|
36 |
-#ifndef __OPENVPN_X509_CERT_T_DECLARED |
|
37 |
-#define __OPENVPN_X509_CERT_T_DECLARED |
|
38 |
-typedef mbedtls_x509_crt openvpn_x509_cert_t; |
|
39 |
-#endif |
|
40 |
- |
|
41 |
-/** @name Function for authenticating a new connection from a remote OpenVPN peer |
|
42 |
- * @{ */ |
|
43 |
- |
|
44 |
-/** |
|
45 |
- * Verify that the remote OpenVPN peer's certificate allows setting up a |
|
46 |
- * VPN tunnel. |
|
47 |
- * @ingroup control_tls |
|
48 |
- * |
|
49 |
- * This callback function is called when a new TLS session is being setup to |
|
50 |
- * determine whether the remote OpenVPN peer's certificate is allowed to |
|
51 |
- * connect. It is called for once for every certificate in the chain. The |
|
52 |
- * callback functionality is configured in the \c init_ssl() function, which |
|
53 |
- * calls the mbed TLS library's \c ssl_set_verify_callback() function with \c |
|
54 |
- * verify_callback() as its callback argument. |
|
55 |
- * |
|
56 |
- * It checks *flags and registers the certificate hash. If these steps succeed, |
|
57 |
- * it calls the \c verify_cert() function, which performs OpenVPN-specific |
|
58 |
- * verification. |
|
59 |
- * |
|
60 |
- * @param session_obj - The OpenVPN \c tls_session associated with this object, |
|
61 |
- * as set during SSL session setup. |
|
62 |
- * @param cert - The certificate used by mbed TLS. |
|
63 |
- * @param cert_depth - The depth of the current certificate in the chain, with |
|
64 |
- * 0 being the actual certificate. |
|
65 |
- * @param flags - Whether the remote OpenVPN peer's certificate |
|
66 |
- * passed verification. A value of 0 means it |
|
67 |
- * verified successfully, any other value means it |
|
68 |
- * failed. \c verify_callback() is considered to have |
|
69 |
- * ok'ed this certificate if flags is 0 when it returns. |
|
70 |
- * |
|
71 |
- * @return The return value is 0 unless a fatal error occurred. |
|
72 |
- */ |
|
73 |
-int verify_callback (void *session_obj, mbedtls_x509_crt *cert, int cert_depth, |
|
74 |
- uint32_t *flags); |
|
75 |
- |
|
76 |
-/** @} name Function for authenticating a new connection from a remote OpenVPN peer */ |
|
77 |
- |
|
78 |
-#endif /* SSL_VERIFY_MBEDTLS_H_ */ |