Browse code

Separated OpenSSL-specific parts of the PKCS#11 driver

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

Adriaan de Jong authored on 2011/06/30 23:28:56
Showing 8 changed files
... ...
@@ -114,7 +114,7 @@ openvpn_SOURCES = \
114 114
 	multi.c multi.h \
115 115
         ntlm.c ntlm.h \
116 116
 	occ.c occ.h occ-inline.h \
117
-	pkcs11.c pkcs11.h \
117
+	pkcs11.c pkcs11.h pkcs11_backend.h \
118 118
 	openvpn.c openvpn.h \
119 119
 	openvpn-plugin.h \
120 120
 	options.c options.h \
... ...
@@ -156,6 +156,7 @@ configure.h: Makefile
156 156
 if USE_OPENSSL
157 157
 openvpn_SOURCES += \
158 158
 	crypto_openssl.c crypto_openssl.h \
159
+	pkcs11_openssl.c \
159 160
 	ssl_openssl.c ssl_openssl.h \
160 161
 	ssl_verify_openssl.c ssl_verify_openssl.h
161 162
 endif
... ...
@@ -27,7 +27,6 @@
27 27
 #if defined(ENABLE_PKCS11)
28 28
 
29 29
 #include <pkcs11-helper-1.0/pkcs11h-certificate.h>
30
-#include <pkcs11-helper-1.0/pkcs11h-openssl.h>
31 30
 #include "basic.h"
32 31
 #include "error.h"
33 32
 #include "manage.h"
... ...
@@ -35,6 +34,7 @@
35 35
 #include "pkcs11.h"
36 36
 #include "misc.h"
37 37
 #include "otime.h"
38
+#include "pkcs11_backend.h"
38 39
 
39 40
 static
40 41
 time_t
... ...
@@ -605,16 +605,13 @@ cleanup:
605 605
 }
606 606
 
607 607
 int
608
-SSL_CTX_use_pkcs11 (
609
-	SSL_CTX * const ssl_ctx,
608
+tls_ctx_use_pkcs11 (
609
+	struct tls_root_ctx * const ssl_ctx,
610 610
 	bool pkcs11_id_management,
611 611
 	const char * const pkcs11_id
612 612
 ) {
613
-	X509 *x509 = NULL;
614
-	RSA *rsa = NULL;
615 613
 	pkcs11h_certificate_id_t certificate_id = NULL;
616 614
 	pkcs11h_certificate_t certificate = NULL;
617
-	pkcs11h_openssl_session_t openssl_session = NULL;
618 615
 	CK_RV rv = CKR_OK;
619 616
 
620 617
 	bool ok = false;
... ...
@@ -624,7 +621,7 @@ SSL_CTX_use_pkcs11 (
624 624
 
625 625
 	dmsg (
626 626
 		D_PKCS11_DEBUG,
627
-		"PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
627
+		"PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
628 628
 		(void *)ssl_ctx,
629 629
 		pkcs11_id_management ? 1 : 0,
630 630
 		pkcs11_id
... ...
@@ -689,54 +686,22 @@ SSL_CTX_use_pkcs11 (
689 689
 		goto cleanup;
690 690
 	}
691 691
 
692
-	if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL	) {
693
-		msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
692
+	if (
693
+		(pkcs11_init_tls_session (
694
+		    certificate,
695
+		    ssl_ctx
696
+		))
697
+	) {
698
+		/* Handled by SSL context free */
699
+		certificate = NULL;
694 700
 		goto cleanup;
695 701
 	}
696 702
 
697
-	/*
698
-	 * Will be released by openssl_session
699
-	 */
703
+	/* Handled by SSL context free */
700 704
 	certificate = NULL;
701
-
702
-	if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) {
703
-		msg (M_WARN, "PKCS#11: Unable get rsa object");
704
-		goto cleanup;
705
-	}
706
-
707
-	if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) {
708
-		msg (M_WARN, "PKCS#11: Unable get certificate object");
709
-		goto cleanup;
710
-	}
711
-
712
-	if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)) {
713
-		msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
714
-		goto cleanup;
715
-	}
716
-
717
-	if (!SSL_CTX_use_certificate (ssl_ctx, x509)) {
718
-		msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
719
-		goto cleanup;
720
-	}
721
-
722 705
 	ok = true;
723 706
 
724 707
 cleanup:
725
-	/*
726
-	 * openssl objects have reference
727
-	 * count, so release them
728
-	 */
729
-
730
-	if (x509 != NULL) {
731
-		X509_free (x509);
732
-		x509 = NULL;
733
-	}
734
-
735
-	if (rsa != NULL) {
736
-		RSA_free (rsa);
737
-		rsa = NULL;
738
-	}
739
-
740 708
 	if (certificate != NULL) {
741 709
 		pkcs11h_certificate_freeCertificate (certificate);
742 710
 		certificate = NULL;
... ...
@@ -746,15 +711,10 @@ cleanup:
746 746
 		pkcs11h_certificate_freeCertificateId (certificate_id);
747 747
 		certificate_id = NULL;
748 748
 	}
749
-	
750
-	if (openssl_session != NULL) {
751
-		pkcs11h_openssl_freeSession (openssl_session);
752
-		openssl_session = NULL;
753
-	}
754 749
 
755 750
 	dmsg (
756 751
 		D_PKCS11_DEBUG,
757
-		"PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld",
752
+		"PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld",
758 753
 		ok ? 1 : 0,
759 754
 		rv
760 755
 	);
... ...
@@ -867,13 +827,10 @@ show_pkcs11_ids (
867 867
 	);
868 868
 	for (current = user_certificates;current != NULL; current = current->next) {
869 869
 		pkcs11h_certificate_t certificate = NULL;
870
-		X509 *x509 = NULL;
871
-		BIO *bio = NULL;
872 870
 		char dn[1024] = {0};
873 871
 		char serial[1024] = {0};
874 872
 		char *ser = NULL;
875 873
 		size_t ser_len = 0;
876
-		int n;
877 874
 
878 875
 		if (
879 876
 			(rv = pkcs11h_certificate_serializeCertificateId (
... ...
@@ -918,31 +875,26 @@ show_pkcs11_ids (
918 918
 			goto cleanup1;
919 919
 		}
920 920
 
921
-		if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) {
922
-			msg (M_FATAL, "PKCS#11: Cannot get X509");
921
+		if (
922
+		      (pkcs11_certificate_dn (
923
+				certificate,
924
+				dn,
925
+				sizeof(dn)
926
+		      ))
927
+		) {
923 928
 			goto cleanup1;
924 929
 		}
925 930
 
926
-		X509_NAME_oneline (
927
-			X509_get_subject_name (x509),
928
-			dn,
929
-			sizeof (dn)
930
-		);
931
-
932
-		if ((bio = BIO_new (BIO_s_mem ())) == NULL) {
933
-			msg (M_FATAL, "PKCS#11: Cannot create BIO");
931
+		if (
932
+		      (pkcs11_certificate_serial (
933
+				certificate,
934
+				serial,
935
+				sizeof(serial)
936
+		      ))
937
+		) {
934 938
 			goto cleanup1;
935 939
 		}
936 940
 
937
-		i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509));
938
-		n = BIO_read (bio, serial, sizeof (serial)-1);
939
-		if (n<0) {
940
-			serial[0] = '\x0';
941
-		}
942
-		else {
943
-			serial[n] = 0;
944
-		}
945
-
946 941
 		msg (
947 942
 			M_INFO|M_NOPREFIX|M_NOLF,
948 943
 			(
... ...
@@ -958,10 +910,6 @@ show_pkcs11_ids (
958 958
 		);
959 959
 
960 960
 	cleanup1:
961
-		if (x509 != NULL) {
962
-			X509_free (x509);
963
-			x509 = NULL;
964
-		}
965 961
 
966 962
 		if (certificate != NULL) {
967 963
 			pkcs11h_certificate_freeCertificate (certificate);
... ...
@@ -27,7 +27,7 @@
27 27
 
28 28
 #if defined(ENABLE_PKCS11)
29 29
 
30
-#include <openssl/ssl.h>
30
+#include "ssl_common.h"
31 31
 
32 32
 bool
33 33
 pkcs11_initialize (
... ...
@@ -63,8 +63,8 @@ pkcs11_management_id_get (
63 63
 );
64 64
 
65 65
 int
66
-SSL_CTX_use_pkcs11 (
67
-	SSL_CTX * const ssl_ctx,
66
+tls_ctx_use_pkcs11 (
67
+	struct tls_root_ctx * const ssl_ctx,
68 68
 	bool pkcs11_id_management,
69 69
 	const char * const pkcs11_id
70 70
 );
71 71
new file mode 100644
... ...
@@ -0,0 +1,77 @@
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 SSL library-specific backend
27
+ */
28
+
29
+#ifndef PKCS11_BACKEND_H_
30
+#define PKCS11_BACKEND_H_
31
+
32
+#include "syshead.h"
33
+
34
+#if defined(ENABLE_PKCS11)
35
+
36
+#include "ssl_common.h"
37
+
38
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
39
+
40
+/**
41
+ * Retrieve PKCS #11 Certificate's DN in a printable format.
42
+ *
43
+ * @param certificate 	The PKCS #11 helper certificate object
44
+ * @param dn		Buffer that the certificate subject DN will be placed in.
45
+ * @param dn_len	Size of said buffer.
46
+ *
47
+ * @return 		1 on failure, 0 on success
48
+ */
49
+int pkcs11_certificate_dn (pkcs11h_certificate_t certificate, char *dn,
50
+    size_t dn_len);
51
+
52
+/**
53
+ * Retrieve PKCS #11 Certificate's serial number in a printable format.
54
+ *
55
+ * @param certificate 	The PKCS #11 helper certificate object
56
+ * @param serial	Buffer that the certificate's serial will be placed in.
57
+ * @param serial_len	Size of said buffer.
58
+ *
59
+ * @return 		1 on failure, 0 on success
60
+ */
61
+int pkcs11_certificate_serial (pkcs11h_certificate_t certificate, char *serial,
62
+    size_t serial_len);
63
+
64
+/**
65
+ * Load PKCS #11 Certificate's information into the given TLS context
66
+ *
67
+ * @param certificate 	The PKCS #11 helper certificate object
68
+ * @param ssl_ctx	TLS context to use.
69
+ *
70
+ * @return 		1 on failure, 0 on success
71
+ */
72
+int pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
73
+    struct tls_root_ctx * const ssl_ctx);
74
+
75
+#endif /* defined(ENABLE_PKCS11) */
76
+#endif /* PKCS11_BACKEND_H_ */
0 77
new file mode 100644
... ...
@@ -0,0 +1,188 @@
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 OpenSSL backend
27
+ */
28
+
29
+#include "syshead.h"
30
+
31
+#ifdef ENABLE_PKCS11
32
+
33
+#include "errlevel.h"
34
+#include "pkcs11_backend.h"
35
+#include <pkcs11-helper-1.0/pkcs11h-openssl.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
+
43
+  X509 *x509 = NULL;
44
+  RSA *rsa = NULL;
45
+  pkcs11h_openssl_session_t openssl_session = NULL;
46
+
47
+  if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL)
48
+    {
49
+      msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
50
+      goto cleanup;
51
+    }
52
+
53
+  /*
54
+   * Will be released by openssl_session
55
+   */
56
+  certificate = NULL;
57
+
58
+  if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL)
59
+    {
60
+      msg (M_WARN, "PKCS#11: Unable get rsa object");
61
+      goto cleanup;
62
+    }
63
+
64
+  if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL)
65
+    {
66
+      msg (M_WARN, "PKCS#11: Unable get certificate object");
67
+      goto cleanup;
68
+    }
69
+
70
+  if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx->ctx, rsa))
71
+    {
72
+      msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
73
+      goto cleanup;
74
+    }
75
+
76
+  if (!SSL_CTX_use_certificate (ssl_ctx->ctx, x509))
77
+    {
78
+      msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
79
+      goto cleanup;
80
+    }
81
+  ret = 0;
82
+
83
+cleanup:
84
+  /*
85
+   * Certificate freeing is usually handled by openssl_session.
86
+   * If something went wrong, creating the session we have to do it manually.
87
+   */
88
+  if (certificate != NULL) {
89
+    pkcs11h_certificate_freeCertificate (certificate);
90
+    certificate = NULL;
91
+  }
92
+
93
+  /*
94
+   * openssl objects have reference
95
+   * count, so release them
96
+   */
97
+  if (x509 != NULL)
98
+    {
99
+      X509_free (x509);
100
+      x509 = NULL;
101
+    }
102
+
103
+  if (rsa != NULL)
104
+    {
105
+      RSA_free (rsa);
106
+      rsa = NULL;
107
+    }
108
+
109
+  if (openssl_session != NULL)
110
+    {
111
+      pkcs11h_openssl_freeSession (openssl_session);
112
+      openssl_session = NULL;
113
+    }
114
+  return ret;
115
+}
116
+
117
+int
118
+pkcs11_certificate_dn (pkcs11h_certificate_t certificate, char *dn,
119
+    size_t dn_len)
120
+{
121
+  X509 *x509 = NULL;
122
+  int ret = 1;
123
+
124
+  if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL)
125
+    {
126
+      msg (M_FATAL, "PKCS#11: Cannot get X509");
127
+      ret = 1;
128
+      goto cleanup;
129
+    }
130
+
131
+  X509_NAME_oneline (X509_get_subject_name (x509), dn, dn_len);
132
+
133
+  ret = 0;
134
+
135
+cleanup:
136
+  if (x509 != NULL)
137
+    {
138
+      X509_free (x509);
139
+      x509 = NULL;
140
+    }
141
+
142
+  return ret;
143
+}
144
+
145
+int
146
+pkcs11_certificate_serial (pkcs11h_certificate_t certificate, char *serial,
147
+    size_t serial_len)
148
+{
149
+  X509 *x509 = NULL;
150
+  BIO *bio = NULL;
151
+  int ret = 1;
152
+  int n;
153
+
154
+  if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL)
155
+    {
156
+      msg (M_FATAL, "PKCS#11: Cannot get X509");
157
+      goto cleanup;
158
+    }
159
+
160
+  if ((bio = BIO_new (BIO_s_mem ())) == NULL)
161
+    {
162
+      msg (M_FATAL, "PKCS#11: Cannot create BIO");
163
+      goto cleanup;
164
+    }
165
+
166
+  i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509));
167
+  n = BIO_read (bio, serial, serial_len-1);
168
+
169
+  if (n<0) {
170
+    serial[0] = '\x0';
171
+  }
172
+  else {
173
+    serial[n] = 0;
174
+  }
175
+
176
+  ret = 0;
177
+
178
+cleanup:
179
+
180
+  if (x509 != NULL)
181
+    {
182
+      X509_free (x509);
183
+      x509 = NULL;
184
+    }
185
+  return ret;
186
+}
187
+#endif /* ENABLE_PKCS11 */
... ...
@@ -328,8 +328,12 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
328 328
 #ifdef ENABLE_PKCS11
329 329
   else if (options->pkcs11_providers[0])
330 330
     {
331
-      if (0 != tls_ctx_load_pkcs11(new_ctx, options->pkcs11_id_management, options->pkcs11_id))
332
-         goto err;
331
+      if (!tls_ctx_use_pkcs11 (new_ctx, options->pkcs11_id_management, options->pkcs11_id))
332
+	{
333
+	  msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface",
334
+	      options->pkcs11_id);
335
+	  goto err;
336
+	}
333 337
     }
334 338
 #endif
335 339
 #ifdef WIN32
... ...
@@ -158,17 +158,6 @@ int tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
158 158
     bool load_ca_file
159 159
     );
160 160
 
161
-/*
162
- * Load PKCS #11 information for key and cert, and add to library-specific TLS
163
- * context.
164
- *
165
- * TODO: document
166
- */
167
-#ifdef ENABLE_PKCS11
168
-int tls_ctx_load_pkcs11(struct tls_root_ctx *ctx,
169
-    bool pkcs11_id_management, const char *pkcs11_id);
170
-#endif /* ENABLE_PKCS11 */
171
-
172 161
 /**
173 162
  * Use Windows cryptoapi for key and cert, and add to library-specific TLS
174 163
  * context.
... ...
@@ -323,23 +323,6 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
323 323
   return 0;
324 324
 }
325 325
 
326
-#ifdef ENABLE_PKCS11
327
-int
328
-tls_ctx_load_pkcs11(struct tls_root_ctx *ctx, bool pkcs11_id_management,
329
-    const char *pkcs11_id)
330
-{
331
-  ASSERT(NULL != ctx);
332
-
333
-  /* Load Certificate and Private Key */
334
-  if (!SSL_CTX_use_pkcs11 (ctx->ctx, pkcs11_id_management, pkcs11_id))
335
-    {
336
-      msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface", pkcs11_id);
337
-      return 1;
338
-    }
339
-  return 0;
340
-}
341
-#endif /* ENABLE_PKCS11 */
342
-
343 326
 #ifdef WIN32
344 327
 void
345 328
 tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)