Browse code

Added PolarSSL support:

- Crypto library
- SSL library
- PKCS#11 support

For missing features, please see README.polarssl

Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Signed-off-by: David Sommerseth <davids@redhat.com>

Adriaan de Jong authored on 2011/07/01 21:15:11
Showing 17 changed files
... ...
@@ -160,6 +160,13 @@ openvpn_SOURCES += \
160 160
 	ssl_openssl.c ssl_openssl.h \
161 161
 	ssl_verify_openssl.c ssl_verify_openssl.h
162 162
 endif
163
+if USE_POLARSSL
164
+openvpn_SOURCES += \
165
+	crypto_polarssl.c crypto_polarssl.h \
166
+	pkcs11_polarssl.c \
167
+	ssl_polarssl.c ssl_polarssl.h \
168
+	ssl_verify_polarssl.c ssl_verify_polarssl.h
169
+endif
163 170
 
164 171
 dist-hook:
165 172
 	cd $(distdir) && for i in $(EXTRA_DIST) $(SUBDIRS) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done
166 173
new file mode 100644
... ...
@@ -0,0 +1,23 @@
0
+This version of OpenVPN has PolarSSL support. To enable follow the following
1
+instructions:
2
+
3
+To Build and Install,
4
+
5
+	./configure --with-ssl-type=polarssl
6
+	make
7
+	make install
8
+
9
+*************************************************************************
10
+
11
+The following features are missing in the PolarSSL version of OpenVPN:
12
+
13
+ * ca_path support - Loading certificate authorities from a directory
14
+ * PKCS#12 file support
15
+ * Windows CryptoAPI support
16
+ * Management external key support
17
+ * X509 alternative username fields (must be "CN")
18
+
19
+ TODO:
20
+ * serial is in Hex
21
+ * X509 certificate export
22
+ * X.509 tracking
... ...
@@ -291,14 +291,16 @@ AC_ARG_WITH(mem-check,
291 291
 )
292 292
 
293 293
 AC_ARG_WITH([ssl-type],
294
-   [  --with-ssl-type=TYPE  Build with the given SSL library, TYPE = openssl ],
294
+   [  --with-ssl-type=TYPE  Build with the given SSL library, TYPE = openssl or polarssl ],
295 295
    [case "${withval}" in 
296 296
         openssl) SSL_LIB=openssl ;;
297
+        polarssl) SSL_LIB=polarssl ;;
297 298
         *) AC_MSG_ERROR([bad value ${withval} for --with-ssl-type]) ;;
298 299
    esac],
299 300
    [SSL_LIB="openssl"]
300 301
 )
301 302
 AM_CONDITIONAL([USE_OPENSSL], [test x$SSL_LIB = xopenssl])
303
+AM_CONDITIONAL([USE_POLARSSL], [test x$SSL_LIB = xpolarssl])
302 304
 
303 305
 dnl fix search path, to allow compilers to find syshead.h
304 306
 CPPFLAGS="$CPPFLAGS -I${srcdir}"
... ...
@@ -710,6 +712,24 @@ if test "$LZO_STUB" = "yes"; then
710 710
 fi
711 711
 
712 712
 dnl
713
+dnl enable pkcs11 capability
714
+dnl
715
+
716
+if test "$PKCS11" = "yes"; then
717
+   AC_CHECKING([for pkcs11-helper Library and Header files])
718
+   AC_CHECK_HEADER(pkcs11-helper-1.0/pkcs11h-core.h,
719
+	[AC_CHECK_LIB(pkcs11-helper, pkcs11h_initialize,
720
+	    [
721
+		   AC_DEFINE(USE_PKCS11, 1, [Enable PKCS11 capability])
722
+		   OPENVPN_ADD_LIBS(-lpkcs11-helper)
723
+	    ],
724
+	    [AC_MSG_RESULT([pkcs11-helper library not found.])]
725
+	)],
726
+	[AC_MSG_RESULT([pkcs11-helper headers not found.])]
727
+   )
728
+fi
729
+
730
+dnl
713 731
 dnl check for SSL-crypto library
714 732
 dnl
715 733
 
... ...
@@ -752,7 +772,20 @@ if test "$CRYPTO" = "yes"; then
752 752
          [AC_MSG_ERROR([OpenSSL crypto Library is too old.])]
753 753
        )
754 754
    fi
755
-
755
+   if test "$SSL_LIB" = "polarssl"; then
756
+        AC_CHECKING([for PolarSSL Crypto Library and Header files])
757
+        AC_CHECK_HEADER(polarssl/aes.h,
758
+            [AC_CHECK_LIB(polarssl, aes_crypt_cbc,
759
+                [
760
+                    OPENVPN_ADD_LIBS(-lpolarssl)
761
+                    AC_DEFINE(USE_CRYPTO, 1, [Use crypto library])
762
+                    AC_DEFINE(USE_POLARSSL, 1, [Use PolarSSL library])
763
+                ],
764
+                [AC_MSG_ERROR([PolarSSL Crypto library not found.])]
765
+            )],
766
+            [AC_MSG_ERROR([PolarSSL Crypto headers not found.])]
767
+        )
768
+    fi
756 769
    dnl
757 770
    dnl check for OpenSSL-SSL library
758 771
    dnl
... ...
@@ -788,6 +821,20 @@ if test "$CRYPTO" = "yes"; then
788 788
 
789 789
          AC_DEFINE(USE_SSL, 1, [Use OpenSSL SSL library])
790 790
       fi
791
+      if test "$SSL_LIB" = "polarssl"; then
792
+         AC_CHECKING([for PolarSSL SSL Library and Header files])
793
+         AC_CHECK_HEADER(polarssl/ssl.h,
794
+              [AC_CHECK_LIB(polarssl, ssl_init,
795
+              [
796
+                  OPENVPN_ADD_LIBS(-lpolarssl)
797
+                  AC_DEFINE(USE_SSL, 1, [Use SSL library])
798
+                  AC_DEFINE(USE_POLARSSL, 1, [Use PolarSSL library])
799
+              ],
800
+              [AC_MSG_ERROR([PolarSSL SSL library not found.])]
801
+          )],
802
+              [AC_MSG_ERROR([PolarSSL SSL headers not found.])]
803
+          )
804
+       fi
791 805
    fi
792 806
 fi
793 807
 
... ...
@@ -796,22 +843,6 @@ if test "$X509ALTUSERNAME" = "yes"; then
796 796
    AC_DEFINE(ENABLE_X509ALTUSERNAME, 1, [Enable --x509-username-field feature])
797 797
 fi
798 798
 
799
-dnl enable pkcs11 capability
800
-
801
-if test "$PKCS11" = "yes"; then
802
-   AC_CHECKING([for pkcs11-helper Library and Header files])
803
-   AC_CHECK_HEADER(pkcs11-helper-1.0/pkcs11h-core.h,
804
-	[AC_CHECK_LIB(pkcs11-helper, pkcs11h_initialize,
805
-	    [
806
-		   AC_DEFINE(USE_PKCS11, 1, [Enable PKCS11 capability])
807
-		   OPENVPN_ADD_LIBS(-lpkcs11-helper)
808
-	    ],
809
-	    [AC_MSG_RESULT([pkcs11-helper library not found.])]
810
-	)],
811
-	[AC_MSG_RESULT([pkcs11-helper headers not found.])]
812
-   )
813
-fi
814
-
815 799
 dnl enable multi-client mode
816 800
 if test "$MULTI" = "yes"; then
817 801
    AC_DEFINE(ENABLE_CLIENT_SERVER, 1, [Enable client/server capability])
... ...
@@ -35,7 +35,9 @@
35 35
 #ifdef USE_OPENSSL
36 36
 #include "crypto_openssl.h"
37 37
 #endif
38
-
38
+#ifdef USE_POLARSSL
39
+#include "crypto_polarssl.h"
40
+#endif
39 41
 #include "basic.h"
40 42
 
41 43
 
42 44
new file mode 100644
... ...
@@ -0,0 +1,577 @@
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 PolarSSL-specific backend interface
27
+ */
28
+
29
+#include "syshead.h"
30
+
31
+#include "errlevel.h"
32
+#include "basic.h"
33
+#include "buffer.h"
34
+#include "integer.h"
35
+#include "crypto_backend.h"
36
+
37
+#include <polarssl/des.h>
38
+#include <polarssl/md5.h>
39
+#include <polarssl/cipher.h>
40
+#include <polarssl/havege.h>
41
+
42
+/*
43
+ *
44
+ * Hardware engine support. Allows loading/unloading of engines.
45
+ *
46
+ */
47
+
48
+void
49
+crypto_init_lib_engine (const char *engine_name)
50
+{
51
+  msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
52
+      "available");
53
+}
54
+
55
+/*
56
+ *
57
+ * Functions related to the core crypto library
58
+ *
59
+ */
60
+
61
+void
62
+crypto_init_lib (void)
63
+{
64
+}
65
+
66
+void
67
+crypto_uninit_lib (void)
68
+{
69
+  prng_uninit();
70
+}
71
+
72
+void
73
+crypto_clear_error (void)
74
+{
75
+}
76
+
77
+#ifdef DMALLOC
78
+void
79
+crypto_init_dmalloc (void)
80
+{
81
+  msg (M_ERR, "Error: dmalloc support is not available for PolarSSL.");
82
+}
83
+#endif /* DMALLOC */
84
+
85
+void
86
+show_available_ciphers ()
87
+{
88
+  const int *ciphers = cipher_list();
89
+
90
+#ifndef ENABLE_SMALL
91
+  printf ("The following ciphers and cipher modes are available\n"
92
+	  "for use with " PACKAGE_NAME ".  Each cipher shown below may be\n"
93
+	  "used as a parameter to the --cipher option.  The default\n"
94
+	  "key size is shown as well as whether or not it can be\n"
95
+          "changed with the --keysize directive.  Using a CBC mode\n"
96
+	  "is recommended.\n\n");
97
+#endif
98
+
99
+  while (*ciphers != 0)
100
+    {
101
+      const cipher_info_t *info = cipher_info_from_type(*ciphers);
102
+
103
+      if (info && info->mode == POLARSSL_MODE_CBC)
104
+	printf ("%s %d bit default key\n",
105
+		info->name, info->key_length);
106
+
107
+      ciphers++;
108
+    }
109
+  printf ("\n");
110
+}
111
+
112
+void
113
+show_available_digests ()
114
+{
115
+  const int *digests = md_list();
116
+
117
+#ifndef ENABLE_SMALL
118
+  printf ("The following message digests are available for use with\n"
119
+	  PACKAGE_NAME ".  A message digest is used in conjunction with\n"
120
+	  "the HMAC function, to authenticate received packets.\n"
121
+	  "You can specify a message digest as parameter to\n"
122
+	  "the --auth option.\n\n");
123
+#endif
124
+
125
+  while (*digests != 0)
126
+    {
127
+      const md_info_t *info = md_info_from_type(*digests);
128
+
129
+      if (info)
130
+	printf ("%s %d bit default key\n",
131
+		info->name, info->size * 8);
132
+      digests++;
133
+    }
134
+  printf ("\n");
135
+}
136
+
137
+void
138
+show_available_engines ()
139
+{
140
+  printf ("Sorry, PolarSSL hardware crypto engine functionality is not "
141
+      "available\n");
142
+}
143
+
144
+
145
+/*
146
+ *
147
+ * Random number functions, used in cases where we want
148
+ * reasonably strong cryptographic random number generation
149
+ * without depleting our entropy pool.  Used for random
150
+ * IV values and a number of other miscellaneous tasks.
151
+ *
152
+ */
153
+
154
+int
155
+rand_bytes (uint8_t *output, int len)
156
+{
157
+  static havege_state hs = {0};
158
+  static bool hs_initialised = false;
159
+  const int int_size = sizeof(int);
160
+
161
+  if (!hs_initialised)
162
+    {
163
+      /* Initialise PolarSSL RNG */
164
+      havege_init(&hs);
165
+      hs_initialised = true;
166
+    }
167
+
168
+  while (len > 0)
169
+    {
170
+      const int blen 	= min_int (len, int_size);
171
+      const int rand_int 	= havege_rand(&hs);
172
+
173
+      memcpy (output, &rand_int, blen);
174
+      output += blen;
175
+      len -= blen;
176
+    }
177
+  return 1;
178
+}
179
+
180
+/*
181
+ *
182
+ * Key functions, allow manipulation of keys.
183
+ *
184
+ */
185
+
186
+
187
+int
188
+key_des_num_cblocks (const cipher_info_t *kt)
189
+{
190
+  int ret = 0;
191
+  if (kt->type == POLARSSL_CIPHER_DES_CBC)
192
+    ret = 1;
193
+  if (kt->type == POLARSSL_CIPHER_DES_EDE_CBC)
194
+    ret = 2;
195
+  if (kt->type == POLARSSL_CIPHER_DES_EDE3_CBC)
196
+    ret = 3;
197
+
198
+  dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
199
+  return ret;
200
+}
201
+
202
+bool
203
+key_des_check (uint8_t *key, int key_len, int ndc)
204
+{
205
+  int i;
206
+  struct buffer b;
207
+
208
+  buf_set_read (&b, key, key_len);
209
+
210
+  for (i = 0; i < ndc; ++i)
211
+    {
212
+      unsigned char *key = buf_read_alloc(&b, DES_KEY_SIZE);
213
+      if (!key)
214
+	{
215
+	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
216
+	  goto err;
217
+	}
218
+      if (0 != des_key_check_weak(key))
219
+	{
220
+	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
221
+	  goto err;
222
+	}
223
+      if (0 != des_key_check_key_parity(key))
224
+	{
225
+	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
226
+	  goto err;
227
+	}
228
+    }
229
+  return true;
230
+
231
+ err:
232
+  return false;
233
+}
234
+
235
+void
236
+key_des_fixup (uint8_t *key, int key_len, int ndc)
237
+{
238
+  int i;
239
+  struct buffer b;
240
+
241
+  buf_set_read (&b, key, key_len);
242
+  for (i = 0; i < ndc; ++i)
243
+    {
244
+      unsigned char *key = buf_read_alloc(&b, DES_KEY_SIZE);
245
+      if (!key)
246
+	{
247
+	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material");
248
+	  return;
249
+	}
250
+      des_key_set_parity(key);
251
+    }
252
+}
253
+
254
+/*
255
+ *
256
+ * Generic cipher key type functions
257
+ *
258
+ */
259
+
260
+
261
+const cipher_info_t *
262
+cipher_kt_get (const char *ciphername)
263
+{
264
+  const cipher_info_t *cipher = NULL;
265
+
266
+  ASSERT (ciphername);
267
+
268
+  cipher = cipher_info_from_string(ciphername);
269
+
270
+  if (NULL == cipher)
271
+    msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername);
272
+
273
+  if (cipher->key_length/8 > MAX_CIPHER_KEY_LENGTH)
274
+    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)",
275
+	 ciphername,
276
+	 cipher->key_length/8,
277
+	 MAX_CIPHER_KEY_LENGTH);
278
+
279
+  return cipher;
280
+}
281
+
282
+const char *
283
+cipher_kt_name (const cipher_info_t *cipher_kt)
284
+{
285
+  if (NULL == cipher_kt)
286
+    return "[null-cipher]";
287
+  return cipher_kt->name;
288
+}
289
+
290
+int
291
+cipher_kt_key_size (const cipher_info_t *cipher_kt)
292
+{
293
+  if (NULL == cipher_kt)
294
+    return 0;
295
+  return cipher_kt->key_length/8;
296
+}
297
+
298
+int
299
+cipher_kt_iv_size (const cipher_info_t *cipher_kt)
300
+{
301
+  if (NULL == cipher_kt)
302
+    return 0;
303
+  return cipher_kt->iv_size;
304
+}
305
+
306
+int
307
+cipher_kt_block_size (const cipher_info_t *cipher_kt)
308
+{
309
+  if (NULL == cipher_kt)
310
+    return 0;
311
+  return cipher_kt->block_size;
312
+}
313
+
314
+bool
315
+cipher_kt_mode (const cipher_info_t *cipher_kt)
316
+{
317
+  ASSERT(NULL != cipher_kt);
318
+  return cipher_kt->mode;
319
+}
320
+
321
+
322
+/*
323
+ *
324
+ * Generic cipher context functions
325
+ *
326
+ */
327
+
328
+
329
+void
330
+cipher_ctx_init (cipher_context_t *ctx, uint8_t *key, int key_len,
331
+    const cipher_info_t *kt, int enc, const char *prefix)
332
+{
333
+  struct gc_arena gc = gc_new ();
334
+
335
+  ASSERT(NULL != kt && NULL != ctx);
336
+
337
+  CLEAR (*ctx);
338
+
339
+  if (0 != cipher_init_ctx(ctx, kt))
340
+    msg (M_FATAL, "PolarSSL cipher context init #1");
341
+
342
+  if (0 != cipher_setkey(ctx, key, key_len*8, enc))
343
+    msg (M_FATAL, "PolarSSL cipher set key");
344
+
345
+  msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key",
346
+       prefix,
347
+       cipher_kt_name(kt),
348
+       cipher_get_key_size(ctx));
349
+
350
+  /* make sure we used a big enough key */
351
+  ASSERT (ctx->key_length <= key_len*8);
352
+
353
+  dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix,
354
+       format_hex (key, key_len, 0, &gc));
355
+  dmsg (D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d",
356
+       prefix,
357
+       cipher_get_block_size(ctx),
358
+       cipher_get_iv_size(ctx));
359
+
360
+  gc_free (&gc);
361
+}
362
+
363
+void cipher_ctx_cleanup (cipher_context_t *ctx)
364
+{
365
+  cipher_free_ctx(ctx);
366
+}
367
+
368
+int cipher_ctx_iv_length (const cipher_context_t *ctx)
369
+{
370
+  return cipher_get_iv_size(ctx);
371
+}
372
+
373
+int cipher_ctx_block_size(const cipher_context_t *ctx)
374
+{
375
+  return cipher_get_block_size(ctx);
376
+}
377
+
378
+int cipher_ctx_mode (const cipher_context_t *ctx)
379
+{
380
+  ASSERT(NULL != ctx);
381
+
382
+  return cipher_kt_mode(ctx->cipher_info);
383
+}
384
+
385
+int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)
386
+{
387
+  return 0 == cipher_reset(ctx, iv_buf);
388
+}
389
+
390
+int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
391
+    uint8_t *src, int src_len)
392
+{
393
+  return 0 == cipher_update(ctx, src, src_len, dst, dst_len);
394
+}
395
+
396
+int cipher_ctx_final (cipher_context_t *ctx, uint8_t *dst, int *dst_len)
397
+{
398
+  return 0 == cipher_finish(ctx, dst, dst_len);
399
+}
400
+
401
+void
402
+cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_SIZE],
403
+    unsigned char *src,
404
+    unsigned char *dst)
405
+{
406
+    des_context ctx;
407
+
408
+    des_setkey_enc(&ctx, key);
409
+    des_crypt_ecb(&ctx, src, dst);
410
+}
411
+
412
+
413
+
414
+/*
415
+ *
416
+ * Generic message digest information functions
417
+ *
418
+ */
419
+
420
+
421
+const md_info_t *
422
+md_kt_get (const char *digest)
423
+{
424
+  const md_info_t *md = NULL;
425
+  ASSERT (digest);
426
+
427
+  md = md_info_from_string(digest);
428
+  if (!md)
429
+    msg (M_FATAL, "Message hash algorithm '%s' not found", digest);
430
+  if (md->size > MAX_HMAC_KEY_LENGTH)
431
+    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)",
432
+	 digest,
433
+	 md->size,
434
+	 MAX_HMAC_KEY_LENGTH);
435
+  return md;
436
+}
437
+
438
+const char *
439
+md_kt_name (const md_info_t *kt)
440
+{
441
+  if (NULL == kt)
442
+    return "[null-digest]";
443
+  return md_get_name (kt);
444
+}
445
+
446
+int
447
+md_kt_size (const md_info_t *kt)
448
+{
449
+  if (NULL == kt)
450
+    return 0;
451
+  return md_get_size(kt);
452
+}
453
+
454
+/*
455
+ *
456
+ * Generic message digest functions
457
+ *
458
+ */
459
+
460
+int
461
+md_full (const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst)
462
+{
463
+  return 0 == md(kt, src, src_len, dst);
464
+}
465
+
466
+
467
+void
468
+md_ctx_init (md_context_t *ctx, const md_info_t *kt)
469
+{
470
+  ASSERT(NULL != ctx && NULL != kt);
471
+
472
+  CLEAR(*ctx);
473
+
474
+  ASSERT(0 == md_starts(kt, ctx));
475
+}
476
+
477
+void
478
+md_ctx_cleanup(md_context_t *ctx)
479
+{
480
+  ASSERT(0 == md_free_ctx(ctx));
481
+}
482
+
483
+int
484
+md_ctx_size (const md_context_t *ctx)
485
+{
486
+  if (NULL == ctx)
487
+    return 0;
488
+  return md_get_size(ctx->md_info);
489
+}
490
+
491
+void
492
+md_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
493
+{
494
+  ASSERT(0 == md_update(ctx, src, src_len));
495
+}
496
+
497
+void
498
+md_ctx_final (md_context_t *ctx, uint8_t *dst)
499
+{
500
+  ASSERT(0 == md_finish(ctx, dst));
501
+}
502
+
503
+
504
+/*
505
+ *
506
+ * Generic HMAC functions
507
+ *
508
+ */
509
+
510
+
511
+/*
512
+ * TODO: re-enable dmsg for crypto debug
513
+ */
514
+void
515
+hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt,
516
+    const char *prefix)
517
+{
518
+  struct gc_arena gc = gc_new ();
519
+
520
+  ASSERT(NULL != kt && NULL != ctx);
521
+
522
+  CLEAR(*ctx);
523
+
524
+  ASSERT(0 == md_hmac_starts(kt, ctx, key, key_len));
525
+
526
+  if (prefix)
527
+    msg (D_HANDSHAKE,
528
+	"%s: Using %d bit message hash '%s' for HMAC authentication",
529
+	prefix, md_get_size(kt) * 8, md_get_name(kt));
530
+
531
+  /* make sure we used a big enough key */
532
+  ASSERT (md_get_size(kt) <= key_len);
533
+
534
+  if (prefix)
535
+    dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix,
536
+	format_hex (key, key_len, 0, &gc));
537
+//  if (prefix)
538
+//    dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d",
539
+//         prefix,
540
+//         md_get_size(md_info),
541
+//         EVP_MD_block_size (md_info));
542
+
543
+  gc_free (&gc);
544
+}
545
+
546
+void
547
+hmac_ctx_cleanup(md_context_t *ctx)
548
+{
549
+  ASSERT(0 == md_free_ctx(ctx));
550
+}
551
+
552
+int
553
+hmac_ctx_size (const md_context_t *ctx)
554
+{
555
+  if (NULL == ctx)
556
+    return 0;
557
+  return md_get_size(ctx->md_info);
558
+}
559
+
560
+void
561
+hmac_ctx_reset (md_context_t *ctx)
562
+{
563
+  ASSERT(0 == md_hmac_reset(ctx));
564
+}
565
+
566
+void
567
+hmac_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
568
+{
569
+  ASSERT(0 == md_hmac_update(ctx, src, src_len));
570
+}
571
+
572
+void
573
+hmac_ctx_final (md_context_t *ctx, uint8_t *dst)
574
+{
575
+  ASSERT(0 == md_hmac_finish(ctx, dst));
576
+}
0 577
new file mode 100644
... ...
@@ -0,0 +1,71 @@
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 PolarSSL-specific backend interface
27
+ */
28
+
29
+#ifndef CRYPTO_POLARSSL_H_
30
+#define CRYPTO_POLARSSL_H_
31
+
32
+#include <polarssl/cipher.h>
33
+#include <polarssl/md.h>
34
+
35
+/** Generic cipher key type %context. */
36
+typedef cipher_info_t cipher_kt_t;
37
+
38
+/** Generic message digest key type %context. */
39
+typedef md_info_t md_kt_t;
40
+
41
+/** Generic cipher %context. */
42
+typedef cipher_context_t cipher_ctx_t;
43
+
44
+/** Generic message digest %context. */
45
+typedef md_context_t md_ctx_t;
46
+
47
+/** Generic HMAC %context. */
48
+typedef md_context_t hmac_ctx_t;
49
+
50
+/** Maximum length of an IV */
51
+#define OPENVPN_MAX_IV_LENGTH 	POLARSSL_MAX_IV_LENGTH
52
+
53
+/** Cipher is in CBC mode */
54
+#define OPENVPN_MODE_CBC 	POLARSSL_MODE_CBC
55
+
56
+/** Cipher is in OFB mode */
57
+#define OPENVPN_MODE_OFB 	POLARSSL_MODE_OFB
58
+
59
+/** Cipher is in CFB mode */
60
+#define OPENVPN_MODE_CFB 	POLARSSL_MODE_CFB
61
+
62
+/** Cipher should encrypt */
63
+#define OPENVPN_OP_ENCRYPT 	POLARSSL_ENCRYPT
64
+
65
+/** Cipher should decrypt */
66
+#define OPENVPN_OP_DECRYPT 	POLARSSL_DECRYPT
67
+
68
+#define MD5_DIGEST_LENGTH 	16
69
+
70
+#endif /* CRYPTO_POLARSSL_H_ */
... ...
@@ -79,9 +79,11 @@
79 79
  *
80 80
  * @subsection key_generation_random Source of random material
81 81
  *
82
- * OpenVPN uses the OpenSSL library as its source of random material. More
83
- * specifically, the \c RAND_bytes() function is called to supply
84
- * cryptographically strong pseudo-random data.  The following links
82
+ * OpenVPN uses the either the OpenSSL library or the PolarSSL library as its
83
+ * source of random material.
84
+ *
85
+ * In OpenSSL, the \c RAND_bytes() function is called
86
+ * to supply cryptographically strong pseudo-random data.  The following links
85 87
  * contain more information on this subject:
86 88
  * - For OpenSSL's \c RAND_bytes() function:
87 89
  *   http://www.openssl.org/docs/crypto/RAND_bytes.html
... ...
@@ -90,6 +92,9 @@
90 90
  * - For OpenSSL's support for external crypto modules:
91 91
  *   http://www.openssl.org/docs/crypto/engine.html
92 92
  *
93
+ * In PolarSSL, the Havege random number generator is used. For details, see
94
+ * the PolarSSL documentation.
95
+ *
93 96
  * @section key_generation_exchange Key exchange:
94 97
  *
95 98
  * The %key exchange process is initiated by the OpenVPN process running
... ...
@@ -28,6 +28,9 @@
28 28
 #ifdef USE_OPENSSL
29 29
 #include "ssl_verify_openssl.h"
30 30
 #endif
31
+#ifdef USE_POLARSSL
32
+#include "ssl_verify_polarssl.h"
33
+#endif
31 34
 
32 35
 #define OPENVPN_PLUGIN_VERSION 3
33 36
 
... ...
@@ -508,7 +508,9 @@ static const char usage_message[] =
508 508
   "--keysize n     : Size of cipher key in bits (optional).\n"
509 509
   "                  If unspecified, defaults to cipher-specific default.\n"
510 510
 #endif
511
+#ifndef USE_POLARSSL
511 512
   "--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n"
513
+#endif
512 514
   "--no-replay     : Disable replay protection.\n"
513 515
   "--mute-replay-warnings : Silence the output of replay warnings to log file.\n"
514 516
   "--replay-window n [t]  : Use a replay protection sliding window of size n\n"
... ...
@@ -529,13 +531,15 @@ static const char usage_message[] =
529 529
   "                  number, such as 1 (default), 2, etc.\n"
530 530
   "--ca file       : Certificate authority file in .pem format containing\n"
531 531
   "                  root certificate.\n"
532
+#ifndef USE_POLARSSL
532 533
   "--capath dir    : A directory of trusted certificates (CAs"
533 534
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
534 535
   " and CRLs).\n"
535
-#else
536
+#else /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
536 537
   ").\n"
537 538
   "                  WARNING: no support of CRL available with this version.\n"
538
-#endif
539
+#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
540
+#endif /* USE_POLARSSL */
539 541
   "--dh file       : File containing Diffie Hellman parameters\n"
540 542
   "                  in .pem format (for --tls-server only).\n"
541 543
   "                  Use \"openssl dhparam -out dh1024.pem 1024\" to generate.\n"
... ...
@@ -590,7 +594,7 @@ static const char usage_message[] =
590 590
   "                  nsCertType designation t = 'client' | 'server'.\n"
591 591
   "--x509-track x  : Save peer X509 attribute x in environment for use by\n"
592 592
   "                  plugins and management interface.\n"
593
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
593
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L || USE_POLARSSL
594 594
   "--remote-cert-ku v ... : Require that the peer certificate was signed with\n"
595 595
   "                  explicit key usage, you can specify more than one value.\n"
596 596
   "                  value should be given in hex format.\n"
... ...
@@ -600,7 +604,7 @@ static const char usage_message[] =
600 600
   "--remote-cert-tls t: Require that peer certificate was signed with explicit\n"
601 601
   "                  key usage and extended key usage based on RFC3280 TLS rules.\n"
602 602
   "                  t = 'client' | 'server'.\n"
603
-#endif				/* OPENSSL_VERSION_NUMBER */
603
+#endif				/* OPENSSL_VERSION_NUMBER || USE_POLARSSL */
604 604
 #endif				/* USE_SSL */
605 605
 #ifdef ENABLE_PKCS11
606 606
   "\n"
... ...
@@ -1537,7 +1541,9 @@ show_settings (const struct options *o)
1537 1537
   SHOW_STR (prng_hash);
1538 1538
   SHOW_INT (prng_nonce_secret_len);
1539 1539
   SHOW_INT (keysize);
1540
+#ifndef USE_POLARSSL
1540 1541
   SHOW_BOOL (engine);
1542
+#endif /* USE_POLARSSL */
1541 1543
   SHOW_BOOL (replay);
1542 1544
   SHOW_BOOL (mute_replay_warnings);
1543 1545
   SHOW_INT (replay_window);
... ...
@@ -2268,8 +2274,13 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
2268 2268
         }
2269 2269
       else
2270 2270
         {
2271
+#ifdef USE_POLARSSL
2272
+	  if (!(options->ca_file))
2273
+	    msg(M_USAGE, "You must define CA file (--ca)");
2274
+#else
2271 2275
 	  if ((!(options->ca_file)) && (!(options->ca_path)))
2272 2276
 	    msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)");
2277
+#endif
2273 2278
 	  if (pull)
2274 2279
 	    {
2275 2280
 	      const int sum = (options->cert_file != NULL) + (options->priv_key_file != NULL);
... ...
@@ -6114,6 +6125,7 @@ add_option (struct options *options,
6114 6114
       VERIFY_PERMISSION (OPT_P_GENERAL);
6115 6115
       options->test_crypto = true;
6116 6116
     }
6117
+#ifndef USE_POLARSSL
6117 6118
   else if (streq (p[0], "engine"))
6118 6119
     {
6119 6120
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -6124,6 +6136,7 @@ add_option (struct options *options,
6124 6124
       else
6125 6125
 	options->engine = "auto";
6126 6126
     }  
6127
+#endif /* USE_POLARSSL */
6127 6128
 #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
6128 6129
   else if (streq (p[0], "keysize") && p[1])
6129 6130
     {
... ...
@@ -6166,11 +6179,13 @@ add_option (struct options *options,
6166 6166
 	}
6167 6167
 #endif
6168 6168
     }
6169
+#ifndef USE_POLARSSL
6169 6170
   else if (streq (p[0], "capath") && p[1])
6170 6171
     {
6171 6172
       VERIFY_PERMISSION (OPT_P_GENERAL);
6172 6173
       options->ca_path = p[1];
6173 6174
     }
6175
+#endif /* USE_POLARSSL */
6174 6176
   else if (streq (p[0], "dh") && p[1])
6175 6177
     {
6176 6178
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -6322,7 +6337,7 @@ add_option (struct options *options,
6322 6322
 	  goto err;
6323 6323
 	}
6324 6324
     }
6325
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6325
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L || USE_POLARSSL
6326 6326
   else if (streq (p[0], "remote-cert-ku"))
6327 6327
     {
6328 6328
       int j;
6329 6329
new file mode 100644
... ...
@@ -0,0 +1,121 @@
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 PolarSSL backend
27
+ */
28
+
29
+#include "syshead.h"
30
+
31
+#if defined(ENABLE_PKCS11)
32
+
33
+#include "errlevel.h"
34
+#include "pkcs11_backend.h"
35
+#include <polarssl/pkcs11.h>
36
+
37
+int
38
+pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
39
+    struct tls_root_ctx * const ssl_ctx)
40
+{
41
+  int ret = 1;
42
+  pkcs11_context pkcs11_ctx;
43
+
44
+  ASSERT (NULL != ssl_ctx);
45
+
46
+  if (pkcs11_x509_cert_init(ssl_ctx->crt_chain, certificate)) {
47
+      msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
48
+      goto cleanup;
49
+  }
50
+
51
+  ssl_ctx->priv_key_pkcs11 = malloc(sizeof(pkcs11_context));
52
+
53
+  if (ssl_ctx->priv_key_pkcs11 == NULL) {
54
+      msg (M_FATAL, "PKCS#11: Cannot allocate PolarSSL private key object");
55
+      goto cleanup;
56
+  }
57
+
58
+  if (pkcs11_priv_key_init(ssl_ctx->priv_key_pkcs11, certificate)) {
59
+      msg (M_FATAL, "PKCS#11: Cannot initialize PolarSSL private key object");
60
+      goto cleanup;
61
+  }
62
+
63
+  ret = 0;
64
+
65
+cleanup:
66
+  return ret;
67
+}
68
+
69
+int
70
+pkcs11_certificate_dn (pkcs11h_certificate_t cert, char *dn,
71
+    size_t dn_len)
72
+{
73
+  int ret = 1;
74
+
75
+  x509_cert polar_cert = {0};
76
+
77
+  if (pkcs11_x509_cert_init(&polar_cert, cert)) {
78
+      msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
79
+      goto cleanup;
80
+  }
81
+
82
+  if (-1 == x509parse_dn_gets (dn, dn_len, &polar_cert.subject)) {
83
+      msg (M_FATAL, "PKCS#11: PolarSSL cannot parse subject");
84
+      goto cleanup;
85
+  }
86
+
87
+  ret = 0;
88
+
89
+cleanup:
90
+  x509_free(&polar_cert);
91
+
92
+  return ret;
93
+}
94
+
95
+int
96
+pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial,
97
+    size_t serial_len)
98
+{
99
+  int ret = 1;
100
+
101
+  x509_cert polar_cert = {0};
102
+
103
+  if (pkcs11_x509_cert_init(&polar_cert, cert)) {
104
+      msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
105
+      goto cleanup;
106
+  }
107
+
108
+  if (-1 == x509parse_serial_gets (serial, serial_len, &polar_cert.serial)) {
109
+      msg (M_FATAL, "PKCS#11: PolarSSL cannot parse serial");
110
+      goto cleanup;
111
+  }
112
+
113
+  ret = 0;
114
+
115
+cleanup:
116
+  x509_free(&polar_cert);
117
+
118
+  return ret;
119
+}
120
+#endif /* defined(ENABLE_PKCS11) */
... ...
@@ -36,6 +36,10 @@
36 36
 #ifdef USE_OPENSSL
37 37
 #include "ssl_openssl.h"
38 38
 #endif
39
+#ifdef USE_POLARSSL
40
+#include "ssl_polarssl.h"
41
+#include "ssl_verify_polarssl.h"
42
+#endif
39 43
 
40 44
 
41 45
 /*
42 46
new file mode 100644
... ...
@@ -0,0 +1,848 @@
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 PolarSSL Backend
27
+ */
28
+
29
+#include "syshead.h"
30
+#include "errlevel.h"
31
+#include "ssl_backend.h"
32
+#include "buffer.h"
33
+#include "misc.h"
34
+#include "manage.h"
35
+#include "ssl_common.h"
36
+
37
+#include "ssl_verify_polarssl.h"
38
+
39
+void
40
+tls_init_lib()
41
+{
42
+}
43
+
44
+void
45
+tls_free_lib()
46
+{
47
+}
48
+
49
+void
50
+tls_clear_error()
51
+{
52
+}
53
+
54
+static int default_ciphers[] =
55
+{
56
+    SSL_EDH_RSA_AES_256_SHA,
57
+    SSL_EDH_RSA_CAMELLIA_256_SHA,
58
+    SSL_EDH_RSA_AES_128_SHA,
59
+    SSL_EDH_RSA_CAMELLIA_128_SHA,
60
+    SSL_EDH_RSA_DES_168_SHA,
61
+    SSL_RSA_AES_256_SHA,
62
+    SSL_RSA_CAMELLIA_256_SHA,
63
+    SSL_RSA_AES_128_SHA,
64
+    SSL_RSA_CAMELLIA_128_SHA,
65
+    SSL_RSA_DES_168_SHA,
66
+    SSL_RSA_RC4_128_SHA,
67
+    SSL_RSA_RC4_128_MD5,
68
+    0
69
+};
70
+
71
+void
72
+tls_ctx_server_new(struct tls_root_ctx *ctx)
73
+{
74
+  ASSERT(NULL != ctx);
75
+  CLEAR(*ctx);
76
+
77
+  ALLOC_OBJ_CLEAR(ctx->hs, havege_state);
78
+  havege_init(ctx->hs);
79
+
80
+  ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context);
81
+  ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context);
82
+
83
+  ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_cert);
84
+  ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_cert);
85
+
86
+
87
+  ctx->endpoint = SSL_IS_SERVER;
88
+  ctx->initialised = true;
89
+}
90
+
91
+void
92
+tls_ctx_client_new(struct tls_root_ctx *ctx)
93
+{
94
+  ASSERT(NULL != ctx);
95
+
96
+  CLEAR(*ctx);
97
+
98
+  ALLOC_OBJ_CLEAR(ctx->hs, havege_state);
99
+  havege_init(ctx->hs);
100
+
101
+  ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context);
102
+  ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context);
103
+
104
+  ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_cert);
105
+  ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_cert);
106
+
107
+  ctx->endpoint = SSL_IS_CLIENT;
108
+  ctx->initialised = true;
109
+}
110
+
111
+void
112
+tls_ctx_free(struct tls_root_ctx *ctx)
113
+{
114
+  if (ctx)
115
+    {
116
+      rsa_free(ctx->priv_key);
117
+      free(ctx->priv_key);
118
+
119
+      x509_free(ctx->ca_chain);
120
+      free(ctx->ca_chain);
121
+
122
+      x509_free(ctx->crt_chain);
123
+      free(ctx->crt_chain);
124
+
125
+      dhm_free(ctx->dhm_ctx);
126
+      free(ctx->dhm_ctx);
127
+
128
+#if defined(ENABLE_PKCS11)
129
+      if (ctx->priv_key_pkcs11 != NULL) {
130
+	  pkcs11_priv_key_free(ctx->priv_key_pkcs11);
131
+	  free(ctx->priv_key_pkcs11);
132
+      }
133
+#endif
134
+
135
+      free(ctx->hs);
136
+
137
+      if (ctx->allowed_ciphers)
138
+	free(ctx->allowed_ciphers);
139
+
140
+      CLEAR(*ctx);
141
+
142
+      ctx->initialised = false;
143
+
144
+    }
145
+}
146
+
147
+bool
148
+tls_ctx_initialised(struct tls_root_ctx *ctx)
149
+{
150
+  ASSERT(NULL != ctx);
151
+  return ctx->initialised;
152
+}
153
+
154
+void
155
+tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
156
+{
157
+}
158
+
159
+void
160
+tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
161
+{
162
+  char *tmp_ciphers, *tmp_ciphers_orig;
163
+  int i, cipher_count;
164
+  int ciphers_len = strlen (ciphers);
165
+
166
+  ASSERT (NULL != ctx);
167
+  ASSERT (0 != ciphers_len);
168
+
169
+  /* Get number of ciphers */
170
+  for (i = 0, cipher_count = 1; i < ciphers_len; i++)
171
+    if (ciphers[i] == ':')
172
+      cipher_count++;
173
+
174
+  /* Allocate an array for them */
175
+  ALLOC_ARRAY_CLEAR(ctx->allowed_ciphers, int, cipher_count+1)
176
+
177
+  /* Parse allowed ciphers, getting IDs */
178
+  i = 0;
179
+  tmp_ciphers_orig = tmp_ciphers = strdup(ciphers);
180
+  while(tmp_ciphers) {
181
+      ctx->allowed_ciphers[i] = ssl_get_cipher_id (strsep (&tmp_ciphers, ":"));
182
+      if (ctx->allowed_ciphers[i] != 0)
183
+	i++;
184
+  }
185
+  free(tmp_ciphers_orig);
186
+}
187
+
188
+void
189
+tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file
190
+#if ENABLE_INLINE_FILES
191
+    , const char *dh_file_inline
192
+#endif /* ENABLE_INLINE_FILES */
193
+    )
194
+{
195
+#if ENABLE_INLINE_FILES
196
+  if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline)
197
+    {
198
+      if (0 != x509parse_dhm(ctx->dhm_ctx, dh_file_inline, strlen(dh_file_inline)))
199
+	msg (M_FATAL, "Cannot read inline DH parameters");
200
+  }
201
+else
202
+#endif /* ENABLE_INLINE_FILES */
203
+  {
204
+    if (0 != x509parse_dhmfile(ctx->dhm_ctx, dh_file))
205
+      msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file);
206
+  }
207
+
208
+  msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key",
209
+      8 * mpi_size(&ctx->dhm_ctx->P));
210
+}
211
+
212
+int
213
+tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
214
+#if ENABLE_INLINE_FILES
215
+    const char *pkcs12_file_inline,
216
+#endif /* ENABLE_INLINE_FILES */
217
+    bool load_ca_file
218
+    )
219
+{
220
+  msg(M_FATAL, "PKCS #12 files not yet supported for PolarSSL.");
221
+}
222
+
223
+#ifdef WIN32
224
+void
225
+tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
226
+{
227
+  msg(M_FATAL, "Windows CryptoAPI not yet supported for PolarSSL.");
228
+}
229
+#endif /* WIN32 */
230
+
231
+void
232
+tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
233
+#if ENABLE_INLINE_FILES
234
+    const char *cert_file_inline,
235
+#endif
236
+    x509_cert_t **x509
237
+    )
238
+{
239
+  ASSERT(NULL != ctx);
240
+  if (NULL != x509)
241
+    ASSERT(NULL == *x509);
242
+
243
+#if ENABLE_INLINE_FILES
244
+  if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline)
245
+    {
246
+      if (0 != x509parse_crt(ctx->crt_chain, cert_file_inline,
247
+	  strlen(cert_file_inline)))
248
+        msg (M_FATAL, "Cannot load inline certificate file");
249
+    }
250
+  else
251
+#endif /* ENABLE_INLINE_FILES */
252
+    {
253
+      if (0 != x509parse_crtfile(ctx->crt_chain, cert_file))
254
+	msg (M_FATAL, "Cannot load certificate file %s", cert_file);
255
+    }
256
+  if (x509)
257
+    {
258
+      *x509 = ctx->crt_chain;
259
+    }
260
+}
261
+
262
+int
263
+tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file
264
+#if ENABLE_INLINE_FILES
265
+    , const char *priv_key_file_inline
266
+#endif /* ENABLE_INLINE_FILES */
267
+    )
268
+{
269
+  int status;
270
+  ASSERT(NULL != ctx);
271
+
272
+#if ENABLE_INLINE_FILES
273
+  if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline)
274
+    {
275
+      status = x509parse_key(ctx->priv_key,
276
+	  priv_key_file_inline, strlen(priv_key_file_inline),
277
+	  NULL, 0);
278
+      if (POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED == status)
279
+	{
280
+	  char passbuf[512] = {0};
281
+	  pem_password_callback(passbuf, 512, 0, NULL);
282
+	  status = x509parse_key(ctx->priv_key,
283
+	      priv_key_file_inline, strlen(priv_key_file_inline),
284
+	      passbuf, strlen(passbuf));
285
+	}
286
+    }
287
+  else
288
+#endif /* ENABLE_INLINE_FILES */
289
+    {
290
+      status = x509parse_keyfile(ctx->priv_key, priv_key_file, NULL);
291
+      if (POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED == status)
292
+	{
293
+	  char passbuf[512] = {0};
294
+	  pem_password_callback(passbuf, 512, 0, NULL);
295
+	  status = x509parse_keyfile(ctx->priv_key, priv_key_file, passbuf);
296
+	}
297
+    }
298
+  if (0 != status)
299
+    {
300
+#ifdef ENABLE_MANAGEMENT
301
+      if (management && (POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH == status))
302
+	  management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
303
+#endif
304
+      msg (M_WARN, "Cannot load private key file %s", priv_key_file);
305
+      return 1;
306
+    }
307
+
308
+  warn_if_group_others_accessible (priv_key_file);
309
+
310
+  /* TODO: Check Private Key */
311
+//  if (!SSL_CTX_check_private_key (ctx))
312
+//    msg (M_SSLERR, "Private key does not match the certificate");
313
+  return 0;
314
+}
315
+
316
+#ifdef MANAGMENT_EXTERNAL_KEY
317
+
318
+int
319
+tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, x509_cert_t *cert)
320
+{
321
+  msg(M_FATAL, "Use of management external keys not yet supported for PolarSSL.");
322
+
323
+}
324
+
325
+#endif
326
+
327
+void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
328
+#if ENABLE_INLINE_FILES
329
+    const char *ca_file_inline,
330
+#endif
331
+    const char *ca_path, bool tls_server
332
+    )
333
+{
334
+  int status;
335
+
336
+  if (ca_path)
337
+      msg(M_FATAL, "ERROR: PolarSSL cannot handle the capath directive");
338
+
339
+#if ENABLE_INLINE_FILES
340
+  if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
341
+    {
342
+      if (0 != x509parse_crt(ctx->ca_chain, ca_file_inline, strlen(ca_file_inline)));
343
+	msg (M_FATAL, "Cannot load inline CA certificates");
344
+    }
345
+  else
346
+#endif
347
+    {
348
+      /* Load CA file for verifying peer supplied certificate */
349
+      if (0 != x509parse_crtfile(ctx->ca_chain, ca_file))
350
+	msg (M_FATAL, "Cannot load CA certificate file %s", ca_file);
351
+    }
352
+}
353
+
354
+void
355
+tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
356
+#if ENABLE_INLINE_FILES
357
+    , const char *extra_certs_file_inline
358
+#endif
359
+    )
360
+{
361
+  ASSERT(NULL != ctx);
362
+
363
+#if ENABLE_INLINE_FILES
364
+  if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
365
+    {
366
+      if (0 != x509parse_crt(ctx->crt_chain, extra_certs_file_inline,
367
+	  strlen(extra_certs_file_inline)))
368
+        msg (M_FATAL, "Cannot load inline extra-certs file");
369
+    }
370
+  else
371
+#endif /* ENABLE_INLINE_FILES */
372
+    {
373
+      if (0 != x509parse_crtfile(ctx->crt_chain, extra_certs_file))
374
+	msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
375
+    }
376
+}
377
+
378
+/* **************************************
379
+ *
380
+ * Key-state specific functions
381
+ *
382
+ ***************************************/
383
+
384
+/*
385
+ * "Endless buffer"
386
+ */
387
+
388
+static inline void buf_free_entry(buffer_entry *entry)
389
+{
390
+  if (NULL != entry)
391
+    {
392
+      free(entry->data);
393
+      free(entry);
394
+    }
395
+}
396
+
397
+static void buf_free_entries(endless_buffer *buf)
398
+{
399
+  while(buf->first_block)
400
+    {
401
+      buffer_entry *cur_block = buf->first_block;
402
+      buf->first_block = cur_block->next_block;
403
+      buf_free_entry(cur_block);
404
+    }
405
+  buf->last_block = NULL;
406
+}
407
+
408
+static int endless_buf_read( void * ctx, unsigned char * out, int out_len )
409
+{
410
+  endless_buffer *in = (endless_buffer *) ctx;
411
+  int read_len = 0;
412
+
413
+  if (in->first_block == NULL)
414
+    return POLARSSL_ERR_NET_TRY_AGAIN;
415
+
416
+  while (in->first_block != NULL && read_len < out_len)
417
+    {
418
+      int block_len = in->first_block->length - in->data_start;
419
+      if (block_len <= out_len - read_len)
420
+	{
421
+	  buffer_entry *cur_entry = in->first_block;
422
+	  memcpy(out + read_len, cur_entry->data + in->data_start,
423
+	      block_len);
424
+
425
+	  read_len += block_len;
426
+
427
+	  in->first_block = cur_entry->next_block;
428
+	  in->data_start = 0;
429
+
430
+	  if (in->first_block == NULL)
431
+	    in->last_block = NULL;
432
+
433
+	  buf_free_entry(cur_entry);
434
+	}
435
+      else
436
+	{
437
+	  memcpy(out + read_len, in->first_block->data + in->data_start,
438
+	      out_len - read_len);
439
+	  in->data_start += out_len - read_len;
440
+	  read_len = out_len;
441
+	}
442
+    }
443
+
444
+  return read_len;
445
+}
446
+
447
+static int endless_buf_write( void *ctx, unsigned char *in, int len )
448
+{
449
+  endless_buffer *out = (endless_buffer *) ctx;
450
+  buffer_entry *new_block = malloc(sizeof(buffer_entry));
451
+  if (NULL == new_block)
452
+    return POLARSSL_ERR_NET_SEND_FAILED;
453
+
454
+  new_block->data = malloc(len);
455
+  if (NULL == new_block->data)
456
+    {
457
+      free(new_block);
458
+      return POLARSSL_ERR_NET_SEND_FAILED;
459
+    }
460
+
461
+  new_block->length = len;
462
+  new_block->next_block = NULL;
463
+
464
+  memcpy(new_block->data, in, len);
465
+
466
+  if (NULL == out->first_block)
467
+    out->first_block = new_block;
468
+
469
+  if (NULL != out->last_block)
470
+    out->last_block->next_block = new_block;
471
+
472
+  out->last_block = new_block;
473
+
474
+  return len;
475
+}
476
+
477
+static void my_debug( void *ctx, int level, const char *str )
478
+{
479
+  if (level == 1)
480
+    {
481
+      dmsg (D_HANDSHAKE_VERBOSE, "PolarSSL alert: %s", str);
482
+    }
483
+}
484
+
485
+void key_state_ssl_init(struct key_state_ssl *ks_ssl,
486
+    const struct tls_root_ctx *ssl_ctx, bool is_server, void *session)
487
+{
488
+  ASSERT(NULL != ssl_ctx);
489
+  ASSERT(ks_ssl);
490
+  CLEAR(*ks_ssl);
491
+
492
+  ALLOC_OBJ_CLEAR(ks_ssl->ctx, ssl_context);
493
+  if (0 == ssl_init(ks_ssl->ctx))
494
+    {
495
+      /* Initialise SSL context */
496
+      ssl_set_dbg (ks_ssl->ctx, my_debug, NULL);
497
+      ssl_set_endpoint (ks_ssl->ctx, ssl_ctx->endpoint);
498
+      ssl_set_rng (ks_ssl->ctx, havege_rand, ssl_ctx->hs);
499
+      ALLOC_OBJ_CLEAR (ks_ssl->ssn, ssl_session);
500
+      ssl_set_session (ks_ssl->ctx, 0, 0, ks_ssl->ssn );
501
+      if (ssl_ctx->allowed_ciphers)
502
+	ssl_set_ciphers (ks_ssl->ctx, ssl_ctx->allowed_ciphers);
503
+      else
504
+	ssl_set_ciphers (ks_ssl->ctx, default_ciphers);
505
+
506
+      /* Initialise authentication information */
507
+      ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx );
508
+      if (ssl_ctx->priv_key_pkcs11 != NULL)
509
+	ssl_set_own_cert_pkcs11( ks_ssl->ctx, ssl_ctx->crt_chain,
510
+	    ssl_ctx->priv_key_pkcs11 );
511
+      else
512
+	ssl_set_own_cert( ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key );
513
+
514
+      /* Initialise SSL verification */
515
+      ssl_set_authmode (ks_ssl->ctx, SSL_VERIFY_REQUIRED);
516
+      ssl_set_verify (ks_ssl->ctx, verify_callback, session);
517
+      /* TODO: PolarSSL does not currently support sending the CA chain to the client */
518
+      ssl_set_ca_chain (ks_ssl->ctx, ssl_ctx->ca_chain, NULL, NULL );
519
+
520
+      /* Initialise BIOs */
521
+      ALLOC_OBJ_CLEAR (ks_ssl->ct_in, endless_buffer);
522
+      ALLOC_OBJ_CLEAR (ks_ssl->ct_out, endless_buffer);
523
+      ssl_set_bio (ks_ssl->ctx, endless_buf_read, ks_ssl->ct_in,
524
+	  endless_buf_write, ks_ssl->ct_out);
525
+
526
+    }
527
+}
528
+
529
+void
530
+key_state_ssl_free(struct key_state_ssl *ks_ssl)
531
+{
532
+  if (ks_ssl) {
533
+      if (ks_ssl->ctx)
534
+	{
535
+	  ssl_free(ks_ssl->ctx);
536
+	  free(ks_ssl->ctx);
537
+	}
538
+      if (ks_ssl->ssn)
539
+	free(ks_ssl->ssn);
540
+      if (ks_ssl->ct_in) {
541
+	buf_free_entries(ks_ssl->ct_in);
542
+	free(ks_ssl->ct_in);
543
+      }
544
+      if (ks_ssl->ct_out) {
545
+	buf_free_entries(ks_ssl->ct_out);
546
+	free(ks_ssl->ct_out);
547
+      }
548
+      CLEAR(*ks_ssl);
549
+  }
550
+}
551
+
552
+int
553
+key_state_write_plaintext (struct key_state_ssl *ks, struct buffer *buf)
554
+{
555
+  int retval = 0;
556
+  perf_push (PERF_BIO_WRITE_PLAINTEXT);
557
+
558
+  ASSERT (NULL != ks);
559
+  ASSERT (buf);
560
+  ASSERT (buf->len >= 0);
561
+
562
+  if (0 == buf->len)
563
+    {
564
+      return 0;
565
+      perf_pop ();
566
+    }
567
+
568
+  retval = ssl_write(ks->ctx, BPTR(buf), buf->len);
569
+
570
+  if (retval < 0)
571
+    {
572
+      perf_pop ();
573
+      if (POLARSSL_ERR_NET_TRY_AGAIN == retval )
574
+	return 0;
575
+      msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_plaintext error");
576
+      return -1;
577
+    }
578
+
579
+  if (retval != buf->len)
580
+    {
581
+      msg (D_TLS_ERRORS,
582
+	  "TLS ERROR: write tls_write_plaintext incomplete %d/%d",
583
+	  retval, buf->len);
584
+      perf_pop ();
585
+      return -1;
586
+    }
587
+
588
+  /* successful write */
589
+  dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_plaintext %d bytes", retval);
590
+
591
+  memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */
592
+  buf->len = 0;
593
+
594
+  perf_pop ();
595
+  return 1;
596
+}
597
+
598
+int
599
+key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data, int len)
600
+{
601
+  int retval = 0;
602
+  perf_push (PERF_BIO_WRITE_PLAINTEXT);
603
+
604
+  ASSERT (NULL != ks);
605
+  ASSERT (len >= 0);
606
+
607
+  if (0 == len)
608
+    {
609
+      perf_pop ();
610
+      return 0;
611
+    }
612
+
613
+  ASSERT (data);
614
+
615
+  retval = ssl_write(ks->ctx, data, len);
616
+
617
+  if (retval < 0)
618
+    {
619
+      perf_pop ();
620
+      if (POLARSSL_ERR_NET_TRY_AGAIN == retval )
621
+	return 0;
622
+      msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_plaintext_const error");
623
+      return -1;
624
+    }
625
+
626
+  if (retval != len)
627
+    {
628
+      msg (D_TLS_ERRORS,
629
+	  "TLS ERROR: write tls_write_plaintext_const incomplete %d/%d",
630
+	  retval, len);
631
+      perf_pop ();
632
+      return -1;
633
+    }
634
+
635
+  /* successful write */
636
+  dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_plaintext_const %d bytes", retval);
637
+
638
+  perf_pop ();
639
+  return 1;
640
+}
641
+
642
+int
643
+key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf,
644
+    int maxlen)
645
+{
646
+  int retval = 0;
647
+  int len = 0;
648
+
649
+  perf_push (PERF_BIO_READ_CIPHERTEXT);
650
+
651
+  ASSERT (NULL != ks);
652
+  ASSERT (buf);
653
+  ASSERT (buf->len >= 0);
654
+
655
+  if (buf->len)
656
+    {
657
+      perf_pop ();
658
+      return 0;
659
+    }
660
+
661
+  len = buf_forward_capacity (buf);
662
+  if (maxlen < len)
663
+    len = maxlen;
664
+
665
+  retval = endless_buf_read(ks->ct_out, BPTR(buf), len);
666
+
667
+  /* Error during read, check for retry error */
668
+  if (retval < 0)
669
+    {
670
+      perf_pop ();
671
+      if (POLARSSL_ERR_NET_TRY_AGAIN == retval )
672
+	return 0;
673
+      msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error");
674
+      buf->len = 0;
675
+      return -1;
676
+    }
677
+  /* Nothing read, try again */
678
+  if (0 == retval)
679
+    {
680
+      buf->len = 0;
681
+      perf_pop ();
682
+      return 0;
683
+    }
684
+
685
+  /* successful read */
686
+  dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_ciphertext %d bytes", retval);
687
+  buf->len = retval;
688
+  perf_pop ();
689
+  return 1;
690
+}
691
+
692
+int
693
+key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf)
694
+{
695
+  int retval = 0;
696
+  perf_push (PERF_BIO_WRITE_CIPHERTEXT);
697
+
698
+  ASSERT (NULL != ks);
699
+  ASSERT (buf);
700
+  ASSERT (buf->len >= 0);
701
+
702
+  if (0 == buf->len)
703
+    {
704
+      perf_pop ();
705
+      return 0;
706
+    }
707
+
708
+  retval = endless_buf_write(ks->ct_in, BPTR(buf), buf->len);
709
+
710
+  if (retval < 0)
711
+    {
712
+      perf_pop ();
713
+
714
+      if (POLARSSL_ERR_NET_TRY_AGAIN == retval )
715
+	return 0;
716
+      msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext error");
717
+      return -1;
718
+    }
719
+
720
+  if (retval != buf->len)
721
+    {
722
+      msg (D_TLS_ERRORS,
723
+	  "TLS ERROR: write tls_write_ciphertext incomplete %d/%d",
724
+	  retval, buf->len);
725
+      perf_pop ();
726
+      return -1;
727
+    }
728
+
729
+  /* successful write */
730
+  dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_ciphertext %d bytes", retval);
731
+
732
+  memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */
733
+  buf->len = 0;
734
+
735
+  perf_pop ();
736
+  return 1;
737
+}
738
+
739
+int
740
+key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
741
+    int maxlen)
742
+{
743
+  int retval = 0;
744
+  int len = 0;
745
+
746
+  perf_push (PERF_BIO_READ_PLAINTEXT);
747
+
748
+  ASSERT (NULL != ks);
749
+  ASSERT (buf);
750
+  ASSERT (buf->len >= 0);
751
+
752
+  if (buf->len)
753
+    {
754
+      perf_pop ();
755
+      return 0;
756
+    }
757
+
758
+  len = buf_forward_capacity (buf);
759
+  if (maxlen < len)
760
+    len = maxlen;
761
+
762
+  retval = ssl_read(ks->ctx, BPTR(buf), len);
763
+
764
+  /* Error during read, check for retry error */
765
+  if (retval < 0)
766
+    {
767
+      if (POLARSSL_ERR_NET_TRY_AGAIN == retval )
768
+	return 0;
769
+      msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error");
770
+      buf->len = 0;
771
+      perf_pop ();
772
+      return -1;
773
+    }
774
+  /* Nothing read, try again */
775
+  if (0 == retval)
776
+    {
777
+      buf->len = 0;
778
+      perf_pop ();
779
+      return 0;
780
+    }
781
+
782
+  /* successful read */
783
+  dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_plaintext %d bytes", retval);
784
+  buf->len = retval;
785
+
786
+  perf_pop ();
787
+  return 1;
788
+}
789
+
790
+/* **************************************
791
+ *
792
+ * Information functions
793
+ *
794
+ * Print information for the end user.
795
+ *
796
+ ***************************************/
797
+void
798
+print_details (struct key_state_ssl * ks_ssl, const char *prefix)
799
+{
800
+  x509_cert *cert;
801
+  char s1[256];
802
+  char s2[256];
803
+
804
+  s1[0] = s2[0] = 0;
805
+  openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s",
806
+		    prefix,
807
+		    ssl_get_version (ks_ssl->ctx),
808
+		    ssl_get_cipher(ks_ssl->ctx));
809
+
810
+  cert = ks_ssl->ctx->peer_cert;
811
+  if (cert != NULL)
812
+    {
813
+      openvpn_snprintf (s2, sizeof (s2), ", %d bit RSA", cert->rsa.len * 8);
814
+    }
815
+
816
+  msg (D_HANDSHAKE, "%s%s", s1, s2);
817
+}
818
+
819
+void
820
+show_available_tls_ciphers ()
821
+{
822
+  const int *ciphers = ssl_list_ciphers();
823
+
824
+#ifndef ENABLE_SMALL
825
+  printf ("Available TLS Ciphers,\n");
826
+  printf ("listed in order of preference:\n\n");
827
+#endif
828
+
829
+  while (*ciphers != 0)
830
+    {
831
+      printf ("%s\n", ssl_get_cipher_name(*ciphers));
832
+      ciphers++;
833
+    }
834
+  printf ("\n");
835
+}
836
+
837
+void
838
+get_highest_preference_tls_cipher (char *buf, int size)
839
+{
840
+  const char *cipher_name;
841
+  const int *ciphers = ssl_list_ciphers();
842
+  if (*ciphers == 0)
843
+    msg (M_FATAL, "Cannot retrieve list of supported SSL ciphers.");
844
+
845
+  cipher_name = ssl_get_cipher_name(*ciphers);
846
+  strncpynt (buf, cipher_name, size);
847
+}
0 848
new file mode 100644
... ...
@@ -0,0 +1,85 @@
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 PolarSSL Backend
27
+ */
28
+
29
+#ifndef SSL_POLARSSL_H_
30
+#define SSL_POLARSSL_H_
31
+
32
+#include <polarssl/havege.h>
33
+#include <polarssl/ssl.h>
34
+#include "config.h"
35
+
36
+#if defined(ENABLE_PKCS11)
37
+#include <polarssl/pkcs11.h>
38
+#endif
39
+
40
+typedef struct _buffer_entry buffer_entry;
41
+
42
+struct _buffer_entry {
43
+    size_t length;
44
+    uint8_t *data;
45
+    buffer_entry *next_block;
46
+};
47
+
48
+typedef struct {
49
+    size_t data_start;
50
+    buffer_entry *first_block;
51
+    buffer_entry *last_block;
52
+} endless_buffer;
53
+
54
+/**
55
+ * Structure that wraps the TLS context. Contents differ depending on the
56
+ * SSL library used.
57
+ *
58
+ * Either \c priv_key_pkcs11 or \c priv_key must be filled in.
59
+ */
60
+struct tls_root_ctx {
61
+    bool initialised; 		/**< True if the context has been initialised */
62
+
63
+    int endpoint; 		/**< Whether or not this is a server or a client */
64
+
65
+    havege_state *hs;		/**< HAVEGE random number state */
66
+    dhm_context *dhm_ctx;	/**< Diffie-Helmann-Merkle context */
67
+    x509_cert *crt_chain;	/**< Local Certificate chain */
68
+    x509_cert *ca_chain;	/**< CA chain for remote verification */
69
+    rsa_context *priv_key;	/**< Local private key */
70
+#if defined(ENABLE_PKCS11)
71
+    pkcs11_context *priv_key_pkcs11;	/**< PKCS11 private key */
72
+#endif
73
+    int * allowed_ciphers;	/**< List of allowed ciphers for this connection */
74
+};
75
+
76
+struct key_state_ssl {
77
+        ssl_context *ctx;
78
+        ssl_session *ssn;
79
+        endless_buffer *ct_in;
80
+        endless_buffer *ct_out;
81
+};
82
+
83
+
84
+#endif /* SSL_POLARSSL_H_ */
... ...
@@ -326,7 +326,7 @@ verify_peer_cert(const struct tls_options *opt, x509_cert_t *peer_cert,
326 326
 	}
327 327
     }
328 328
 
329
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
329
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L || USE_POLARSSL
330 330
 
331 331
   /* verify certificate ku */
332 332
   if (opt->remote_cert_ku[0] != 0)
... ...
@@ -39,6 +39,9 @@
39 39
 #ifdef USE_OPENSSL
40 40
 #include "ssl_verify_openssl.h"
41 41
 #endif
42
+#ifdef USE_POLARSSL
43
+#include "ssl_verify_polarssl.h"
44
+#endif
42 45
 
43 46
 #include "ssl_verify_backend.h"
44 47
 
45 48
new file mode 100644
... ...
@@ -0,0 +1,446 @@
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 PolarSSL backend
27
+ */
28
+
29
+#include "ssl_verify.h"
30
+#include <polarssl/sha1.h>
31
+
32
+#define MAX_SUBJECT_LENGTH 256
33
+
34
+int
35
+verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
36
+    int preverify_ok)
37
+{
38
+  struct tls_session *session = (struct tls_session *) session_obj;
39
+  unsigned char *sha1_hash = NULL;
40
+
41
+  ASSERT (cert);
42
+  ASSERT (session);
43
+
44
+  session->verified = false;
45
+
46
+  /* Remember certificate hash */
47
+  sha1_hash = x509_get_sha1_hash(cert);
48
+  cert_hash_remember (session, cert_depth, sha1_hash);
49
+  x509_free_sha1_hash(sha1_hash);
50
+
51
+  /* did peer present cert which was signed by our root cert? */
52
+  if (!preverify_ok)
53
+    {
54
+      char subject[MAX_SUBJECT_LENGTH] = {0};
55
+
56
+      /* get the X509 name */
57
+      if (x509parse_dn_gets( subject, MAX_SUBJECT_LENGTH, &cert->subject ) < 0)
58
+	  msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
59
+	      "subject string from certificate", cert_depth);
60
+      else
61
+	msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, %s", cert_depth, subject);
62
+
63
+      return 1;
64
+    }
65
+
66
+  /*
67
+   * verify_cert() returns 1 on success, 0 on failure.
68
+   * PolarSSL expects the opposite.
69
+   */
70
+  return 0 == verify_cert(session, cert, cert_depth);
71
+}
72
+
73
+#ifdef ENABLE_X509ALTUSERNAME
74
+# warning "X509 alt user name not yet supported for PolarSSL"
75
+#endif
76
+
77
+bool
78
+x509_get_username (char *cn, int cn_len,
79
+    char *x509_username_field, x509_cert *cert)
80
+{
81
+  x509_name *name;
82
+
83
+  ASSERT( cn != NULL );
84
+
85
+  name = &cert->subject;
86
+
87
+  /* Find common name */
88
+  while( name != NULL )
89
+  {
90
+      if( memcmp( name->oid.p, OID_CN, OID_SIZE(OID_CN) ) == 0)
91
+	break;
92
+
93
+      name = name->next;
94
+  }
95
+
96
+  /* Not found, return an error if this is the peer's certificate */
97
+  if( name == NULL )
98
+      return 1;
99
+
100
+  /* Found, extract CN */
101
+  if (cn_len > name->val.len)
102
+    memcpy( cn, name->val.p, name->val.len );
103
+  else
104
+    {
105
+      memcpy( cn, name->val.p, cn_len);
106
+      cn[cn_len-1] = '\0';
107
+    }
108
+
109
+  return 0;
110
+}
111
+
112
+char *
113
+x509_get_serial (x509_cert *cert)
114
+{
115
+  int ret = 0;
116
+  int i = 0;
117
+  char *buf = NULL;
118
+  size_t len = cert->serial.len * 3;
119
+
120
+  buf = malloc(len);
121
+  ASSERT(buf);
122
+
123
+  if(x509parse_serial_gets(buf, len-1, &cert->serial) < 0)
124
+    {
125
+      free(buf);
126
+      buf = NULL;
127
+    }
128
+
129
+  return buf;
130
+}
131
+
132
+void
133
+x509_free_serial (char *serial)
134
+{
135
+  if (serial)
136
+    free(serial);
137
+}
138
+
139
+unsigned char *
140
+x509_get_sha1_hash (x509_cert *cert)
141
+{
142
+  unsigned char *sha1_hash = malloc(SHA_DIGEST_LENGTH);
143
+  sha1(cert->tbs.p, cert->tbs.len, sha1_hash);
144
+  return sha1_hash;
145
+}
146
+
147
+void
148
+x509_free_sha1_hash (unsigned char *hash)
149
+{
150
+  if (hash)
151
+    free(hash);
152
+}
153
+
154
+char *
155
+x509_get_subject(x509_cert *cert)
156
+{
157
+  char tmp_subject[MAX_SUBJECT_LENGTH] = {0};
158
+  char *subject = NULL;
159
+
160
+  int ret = 0;
161
+
162
+  ret = x509parse_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject );
163
+  if (ret > 0)
164
+    {
165
+      /* Allocate the required space for the subject */
166
+      subject = malloc(ret + 1);
167
+      strncpy(subject, tmp_subject, ret+1);
168
+    }
169
+
170
+  return subject;
171
+}
172
+
173
+void
174
+x509_free_subject (char *subject)
175
+{
176
+  if (subject)
177
+    free(subject);
178
+}
179
+
180
+/*
181
+ * Save X509 fields to environment, using the naming convention:
182
+ *
183
+ * X509_{cert_depth}_{name}={value}
184
+ */
185
+void
186
+x509_setenv (struct env_set *es, int cert_depth, x509_cert_t *cert)
187
+{
188
+  int i, ret;
189
+  unsigned char c;
190
+  const x509_name *name;
191
+  char s[128];
192
+
193
+  name = &cert->subject;
194
+
195
+  memset( s, 0, sizeof( s ) );
196
+
197
+  while( name != NULL )
198
+    {
199
+      char name_expand[64+8];
200
+
201
+      if( name->oid.len == 2 && memcmp( name->oid.p, OID_X520, 2 ) == 0 )
202
+	{
203
+	  switch( name->oid.p[2] )
204
+	    {
205
+	    case X520_COMMON_NAME:
206
+		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_CN",
207
+		    cert_depth); break;
208
+
209
+	    case X520_COUNTRY:
210
+		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_C",
211
+		    cert_depth); break;
212
+
213
+	    case X520_LOCALITY:
214
+		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_L",
215
+		    cert_depth); break;
216
+
217
+	    case X520_STATE:
218
+		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_ST",
219
+		    cert_depth); break;
220
+
221
+	    case X520_ORGANIZATION:
222
+		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_O",
223
+		    cert_depth); break;
224
+
225
+	    case X520_ORG_UNIT:
226
+		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_OU",
227
+		    cert_depth); break;
228
+
229
+	    default:
230
+		openvpn_snprintf (name_expand, sizeof(name_expand),
231
+		    "X509_%d_0x%02X", cert_depth, name->oid.p[2]);
232
+		break;
233
+	    }
234
+	}
235
+	else if( name->oid.len == 8 && memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
236
+	  {
237
+	    switch( name->oid.p[8] )
238
+	      {
239
+		case PKCS9_EMAIL:
240
+		  openvpn_snprintf (name_expand, sizeof(name_expand),
241
+		      "X509_%d_emailAddress", cert_depth); break;
242
+
243
+		default:
244
+		  openvpn_snprintf (name_expand, sizeof(name_expand),
245
+		      "X509_%d_0x%02X", cert_depth, name->oid.p[8]);
246
+		  break;
247
+	      }
248
+	  }
249
+	else
250
+	  {
251
+	    openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?",
252
+		cert_depth);
253
+	  }
254
+
255
+	for( i = 0; i < name->val.len; i++ )
256
+	{
257
+	    if( i >= (int) sizeof( s ) - 1 )
258
+		break;
259
+
260
+	    c = name->val.p[i];
261
+	    if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
262
+		 s[i] = '?';
263
+	    else s[i] = c;
264
+	}
265
+	s[i] = '\0';
266
+
267
+	/* Check both strings, set environment variable */
268
+	string_mod (name_expand, CC_PRINT, CC_CRLF, '_');
269
+	string_mod ((char*)s, CC_PRINT, CC_CRLF, '_');
270
+	setenv_str (es, name_expand, (char*)s);
271
+
272
+	name = name->next;
273
+    }
274
+}
275
+
276
+bool
277
+x509_verify_ns_cert_type(const x509_cert *cert, const int usage)
278
+{
279
+  if (usage == NS_CERT_CHECK_NONE)
280
+    return true;
281
+  if (usage == NS_CERT_CHECK_CLIENT)
282
+    return ((cert->ext_types & EXT_NS_CERT_TYPE)
283
+	&& (cert->ns_cert_type & NS_CERT_TYPE_SSL_CLIENT));
284
+  if (usage == NS_CERT_CHECK_SERVER)
285
+    return ((cert->ext_types & EXT_NS_CERT_TYPE)
286
+	&& (cert->ns_cert_type & NS_CERT_TYPE_SSL_SERVER));
287
+
288
+  return false;
289
+}
290
+
291
+bool
292
+x509_verify_cert_ku (x509_cert *cert, const unsigned * const expected_ku,
293
+    int expected_len)
294
+{
295
+  bool fFound = false;
296
+
297
+  if(!(cert->ext_types & EXT_KEY_USAGE))
298
+    {
299
+      msg (D_HANDSHAKE, "Certificate does not have key usage extension");
300
+    }
301
+  else
302
+    {
303
+      int i;
304
+      unsigned nku = cert->key_usage;
305
+
306
+      msg (D_HANDSHAKE, "Validating certificate key usage");
307
+      for (i=0;!fFound && i<expected_len;i++)
308
+	{
309
+	  if (expected_ku[i] != 0)
310
+	    {
311
+	      msg (D_HANDSHAKE, "++ Certificate has key usage  %04x, expects "
312
+		  "%04x", nku, expected_ku[i]);
313
+
314
+	      if (nku == expected_ku[i])
315
+		{
316
+		  fFound = true;
317
+		}
318
+	    }
319
+	}
320
+    }
321
+  return fFound;
322
+}
323
+
324
+bool
325
+x509_verify_cert_eku (x509_cert *cert, const char * const expected_oid)
326
+{
327
+  bool fFound = false;
328
+
329
+  if (!(cert->ext_types & EXT_EXTENDED_KEY_USAGE))
330
+    {
331
+      msg (D_HANDSHAKE, "Certificate does not have extended key usage extension");
332
+    }
333
+  else
334
+    {
335
+      x509_sequence *oid_seq = &(cert->ext_key_usage);
336
+
337
+      msg (D_HANDSHAKE, "Validating certificate extended key usage");
338
+      while (oid_seq != NULL)
339
+	{
340
+	  x509_buf *oid = &oid_seq->buf;
341
+	  char oid_num_str[1024];
342
+	  const char *oid_str;
343
+
344
+	  oid_str = x509_oid_get_description(oid);
345
+	  if (oid_str != NULL)
346
+	    {
347
+	      msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
348
+		  oid_str, expected_oid);
349
+	      if (!strcmp (expected_oid, oid_str))
350
+		{
351
+		  fFound = true;
352
+		  break;
353
+		}
354
+	    }
355
+
356
+	  if (0 == x509_oid_get_numeric_string( oid_num_str,
357
+	      sizeof (oid_num_str), oid))
358
+	    {
359
+	      msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
360
+		  oid_num_str, expected_oid);
361
+	      if (!strcmp (expected_oid, oid_num_str))
362
+		{
363
+		  fFound = true;
364
+		  break;
365
+		}
366
+	    }
367
+	  oid_seq = oid_seq->next;
368
+	}
369
+    }
370
+
371
+    return fFound;
372
+}
373
+
374
+const char *
375
+x509_write_cert(x509_cert *peercert, const char *tmp_dir, struct gc_arena *gc)
376
+{
377
+  FILE *peercert_file;
378
+  const char *peercert_filename="";
379
+
380
+  if(!tmp_dir)
381
+      return NULL;
382
+
383
+  /* create tmp file to store peer cert */
384
+  peercert_filename = create_temp_file (tmp_dir, "pcf", gc);
385
+
386
+  /* write peer-cert in tmp-file */
387
+  peercert_file = fopen(peercert_filename, "w+");
388
+  if(!peercert_file)
389
+    {
390
+      msg (M_ERR, "Failed to open temporary file : %s", peercert_filename);
391
+      return NULL;
392
+    }
393
+
394
+//  if(PEM_write_X509(peercert_file,peercert)<0)
395
+//    {
396
+      msg (M_ERR, "PolarSSL does not support writing peer certificate in PEM format");
397
+      fclose(peercert_file);
398
+      return NULL;
399
+//    }
400
+
401
+  fclose(peercert_file);
402
+  return peercert_filename;
403
+}
404
+
405
+/*
406
+ * check peer cert against CRL
407
+ */
408
+bool
409
+x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject)
410
+{
411
+  int retval = 0;
412
+  x509_crl crl = {0};
413
+
414
+  if (x509parse_crlfile(&crl, crl_file) != 0)
415
+    {
416
+      msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);
417
+      goto end;
418
+    }
419
+
420
+  if(cert->issuer_raw.len != crl.issuer_raw.len ||
421
+      memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0)
422
+    {
423
+      msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of "
424
+	  "certificate %s", crl_file, subject);
425
+      retval = 1;
426
+      goto end;
427
+    }
428
+
429
+  if (0 != x509parse_revoked(cert, &crl))
430
+    {
431
+      msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED", subject);
432
+      goto end;
433
+    }
434
+
435
+  retval = 1;
436
+  msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject);
437
+
438
+end:
439
+  x509_crl_free(&crl);
440
+
441
+  if (!retval)
442
+    return true;
443
+
444
+  return false;
445
+}
0 446
new file mode 100644
... ...
@@ -0,0 +1,79 @@
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 PolarSSL backend
27
+ */
28
+
29
+#ifndef SSL_VERIFY_POLARSSL_H_
30
+#define SSL_VERIFY_POLARSSL_H_
31
+
32
+#include "syshead.h"
33
+#include "misc.h"
34
+#include "manage.h"
35
+#include <polarssl/x509.h>
36
+
37
+typedef x509_cert x509_cert_t;
38
+
39
+/** @name Function for authenticating a new connection from a remote OpenVPN peer
40
+ *  @{ */
41
+
42
+/**
43
+ * Verify that the remote OpenVPN peer's certificate allows setting up a
44
+ * VPN tunnel.
45
+ * @ingroup control_tls
46
+ *
47
+ * This callback function is called when a new TLS session is being setup to
48
+ * determine whether the remote OpenVPN peer's certificate is allowed to
49
+ * connect. It is called for once for every certificate in the chain. The
50
+ * callback functionality is configured in the \c init_ssl() function, which
51
+ * calls the PolarSSL library's \c ssl_set_verify_callback() function with \c
52
+ * verify_callback() as its callback argument.
53
+ *
54
+ * It checks preverify_ok, and registers the certificate hash. If these steps
55
+ * succeed, it calls the \c verify_cert() function, which performs
56
+ * OpenVPN-specific verification.
57
+ *
58
+ * @param session_obj  - The OpenVPN \c tls_session associated with this object,
59
+ *                       as set during SSL session setup.
60
+ * @param cert         - The certificate used by PolarSSL.
61
+ * @param cert_depth   - The depth of the current certificate in the chain, with
62
+ *                       0 being the actual certificate.
63
+ * @param preverify_ok - Whether the remote OpenVPN peer's certificate
64
+ *                       past verification.  A value of 1 means it
65
+ *                       verified successfully, 0 means it failed.
66
+ *
67
+ * @return The return value indicates whether the supplied certificate is
68
+ *     allowed to set up a VPN tunnel.  The following values can be
69
+ *     returned:
70
+ *      - \c 0: failure, this certificate is not allowed to connect.
71
+ *      - \c 1: success, this certificate is allowed to connect.
72
+ */
73
+int verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
74
+    int preverify_ok);
75
+
76
+/** @} name Function for authenticating a new connection from a remote OpenVPN peer */
77
+
78
+#endif /* SSL_VERIFY_POLARSSL_H_ */