Browse code

Refactored PKCS#12 key loading

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

Adriaan de Jong authored on 2011/06/29 23:51:16
Showing 5 changed files
... ...
@@ -1989,86 +1989,9 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
1989 1989
 
1990 1990
   if (options->pkcs12_file)
1991 1991
     {
1992
-      /* Use PKCS #12 file for key, cert and CA certs */
1993
-
1994
-      FILE *fp;
1995
-      EVP_PKEY *pkey;
1996
-      X509 *cert;
1997
-      STACK_OF(X509) *ca = NULL;
1998
-      PKCS12 *p12=NULL;
1999
-      int i;
2000
-      char password[256];
2001
-
2002
-#if ENABLE_INLINE_FILES
2003
-      if (!strcmp (options->pkcs12_file, INLINE_FILE_TAG) && options->pkcs12_file_inline)
2004
-	{
2005
-	  BIO *b64 = BIO_new (BIO_f_base64());
2006
-	  BIO *bio = BIO_new_mem_buf ((void *)options->pkcs12_file_inline, (int)strlen(options->pkcs12_file_inline));
2007
-	  ASSERT(b64 && bio);
2008
-	  BIO_push (b64, bio);
2009
-	  p12 = d2i_PKCS12_bio(b64, NULL);
2010
-	  if (!p12)
2011
-	    msg (M_SSLERR, "Error reading inline PKCS#12 file");
2012
-	  BIO_free (b64);
2013
-	  BIO_free (bio);
2014
-	}
2015
-      else
2016
-#endif
2017
-	{
2018
-	  /* Load the PKCS #12 file */
2019
-	  if (!(fp = fopen(options->pkcs12_file, "rb")))
2020
-	    msg (M_SSLERR, "Error opening file %s", options->pkcs12_file);
2021
-	  p12 = d2i_PKCS12_fp(fp, NULL);
2022
-	  fclose (fp);
2023
-	  if (!p12)
2024
-	    msg (M_SSLERR, "Error reading PKCS#12 file %s", options->pkcs12_file);
2025
-	}
2026
-
2027
-      /* Parse the PKCS #12 file */
2028
-      if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
2029
-        {
2030
-          pem_password_callback (password, sizeof(password) - 1, 0, NULL);
2031
-          /* Reparse the PKCS #12 file with password */
2032
-          ca = NULL;
2033
-          if (!PKCS12_parse(p12, password, &pkey, &cert, &ca))
2034
-	    {
2035
-#ifdef ENABLE_MANAGEMENT
2036
-	      if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE))
2037
-		management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
2038
-#endif
2039
-	      PKCS12_free(p12);
2040
-	      goto err;
2041
-	    }
2042
-        }
2043
-      PKCS12_free(p12);
2044
-
2045
-      /* Load Certificate */
2046
-      if (!SSL_CTX_use_certificate (ctx, cert))
2047
-        msg (M_SSLERR, "Cannot use certificate");
2048
-
2049
-      /* Load Private Key */
2050
-      if (!SSL_CTX_use_PrivateKey (ctx, pkey))
2051
-        msg (M_SSLERR, "Cannot use private key");
2052
-      warn_if_group_others_accessible (options->pkcs12_file);
2053
-
2054
-      /* Check Private Key */
2055
-      if (!SSL_CTX_check_private_key (ctx))
2056
-        msg (M_SSLERR, "Private key does not match the certificate");
2057
-
2058
-      /* Set Certificate Verification chain */
2059
-      if (!options->ca_file)
2060
-        {
2061
-          if (ca && sk_X509_num(ca))
2062
-            {
2063
-              for (i = 0; i < sk_X509_num(ca); i++)
2064
-                {
2065
-	          if (!X509_STORE_add_cert(ctx->cert_store,sk_X509_value(ca, i)))
2066
-                    msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)");
2067
-                  if (options->tls_server && !SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i)))
2068
-                    msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
2069
-                }
2070
-            }
2071
-        }
1992
+      if (0 != tls_ctx_load_pkcs12(new_ctx, options->pkcs12_file,
1993
+	  options->pkcs12_file_inline, !options->ca_file))
1994
+        goto err;
2072 1995
     }
2073 1996
   else
2074 1997
     {
... ...
@@ -57,10 +57,6 @@
57 57
 /* Used in the TLS PRF function */
58 58
 #define KEY_EXPANSION_ID "OpenVPN"
59 59
 
60
-/* passwords */
61
-#define UP_TYPE_AUTH        "Auth"
62
-#define UP_TYPE_PRIVATE_KEY "Private Key"
63
-
64 60
 /* packet opcode (high 5 bits) and key-id (low 3 bits) are combined in one byte */
65 61
 #define P_KEY_ID_MASK                  0x07
66 62
 #define P_OPCODE_SHIFT                 3
... ...
@@ -116,7 +116,7 @@ bool tls_ctx_initialised(struct tls_root_ctx *ctx);
116 116
  */
117 117
 void tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags);
118 118
 
119
-/*
119
+/**
120 120
  * Load Diffie Hellman Parameters, and load them into the library-specific
121 121
  * TLS context.
122 122
  *
... ...
@@ -131,7 +131,26 @@ void tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file
131 131
 #endif /* ENABLE_INLINE_FILES */
132 132
     );
133 133
 
134
-/*
134
+/**
135
+ * Load PKCS #12 file for key, cert and (optionally) CA certs, and add to
136
+ * library-specific TLS context.
137
+ *
138
+ * @param ctx			TLS context to use
139
+ * @param pkcs12_file		The file name to load the information from, or
140
+ * 				"[[INLINE]]" in the case of inline files.
141
+ * @param pkcs12_file_inline	A string containing the information
142
+ *
143
+ * @return 			1 if an error occurred, 0 if parsing was
144
+ * 				successful.
145
+ */
146
+int tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
147
+#if ENABLE_INLINE_FILES
148
+    const char *pkcs12_file_inline,
149
+#endif /* ENABLE_INLINE_FILES */
150
+    bool load_ca_file
151
+    );
152
+
153
+/**
135 154
  * Show the TLS ciphers that are available for us to use in the OpenSSL
136 155
  * library.
137 156
  */
... ...
@@ -38,6 +38,10 @@
38 38
 
39 39
 #include "ssl_backend.h"
40 40
 
41
+/* passwords */
42
+#define UP_TYPE_AUTH        "Auth"
43
+#define UP_TYPE_PRIVATE_KEY "Private Key"
44
+
41 45
   /* configuration file boolean options */
42 46
 # define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0)
43 47
 # define SSLF_USERNAME_AS_COMMON_NAME  (1<<1)
... ...
@@ -221,6 +221,98 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file
221 221
   DH_free (dh);
222 222
 }
223 223
 
224
+int
225
+tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
226
+#if ENABLE_INLINE_FILES
227
+    const char *pkcs12_file_inline,
228
+#endif /* ENABLE_INLINE_FILES */
229
+    bool load_ca_file
230
+    )
231
+{
232
+  FILE *fp;
233
+  EVP_PKEY *pkey;
234
+  X509 *cert;
235
+  STACK_OF(X509) *ca = NULL;
236
+  PKCS12 *p12;
237
+  int i;
238
+  char password[256];
239
+
240
+  ASSERT(NULL != ctx);
241
+
242
+#if ENABLE_INLINE_FILES
243
+  if (!strcmp (pkcs12_file, INLINE_FILE_TAG) && pkcs12_file_inline)
244
+    {
245
+      BIO *b64 = BIO_new(BIO_f_base64());
246
+      BIO *bio = BIO_new_mem_buf((void *) pkcs12_file_inline,
247
+	  (int) strlen(pkcs12_file_inline));
248
+      ASSERT(b64 && bio);
249
+      BIO_push(b64, bio);
250
+      p12 = d2i_PKCS12_bio(b64, NULL);
251
+      if (!p12)
252
+	msg(M_SSLERR, "Error reading inline PKCS#12 file");
253
+      BIO_free(b64);
254
+      BIO_free(bio);
255
+    }
256
+  else
257
+#endif
258
+    {
259
+      /* Load the PKCS #12 file */
260
+      if (!(fp = fopen(pkcs12_file, "rb")))
261
+	msg(M_SSLERR, "Error opening file %s", pkcs12_file);
262
+      p12 = d2i_PKCS12_fp(fp, NULL);
263
+      fclose(fp);
264
+      if (!p12)
265
+	msg(M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file);
266
+    }
267
+
268
+  /* Parse the PKCS #12 file */
269
+  if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
270
+   {
271
+     pem_password_callback (password, sizeof(password) - 1, 0, NULL);
272
+     /* Reparse the PKCS #12 file with password */
273
+     ca = NULL;
274
+     if (!PKCS12_parse(p12, password, &pkey, &cert, &ca))
275
+      {
276
+#ifdef ENABLE_MANAGEMENT
277
+	      if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE))
278
+		management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
279
+#endif
280
+	PKCS12_free(p12);
281
+	return 1;
282
+      }
283
+   }
284
+  PKCS12_free(p12);
285
+
286
+  /* Load Certificate */
287
+  if (!SSL_CTX_use_certificate (ctx->ctx, cert))
288
+   msg (M_SSLERR, "Cannot use certificate");
289
+
290
+  /* Load Private Key */
291
+  if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey))
292
+   msg (M_SSLERR, "Cannot use private key");
293
+  warn_if_group_others_accessible (pkcs12_file);
294
+
295
+  /* Check Private Key */
296
+  if (!SSL_CTX_check_private_key (ctx->ctx))
297
+   msg (M_SSLERR, "Private key does not match the certificate");
298
+
299
+  /* Set Certificate Verification chain */
300
+  if (load_ca_file)
301
+   {
302
+     if (ca && sk_X509_num(ca))
303
+      {
304
+	for (i = 0; i < sk_X509_num(ca); i++)
305
+	  {
306
+	      if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i)))
307
+	      msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)");
308
+	    if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i)))
309
+	      msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
310
+	  }
311
+      }
312
+   }
313
+  return 0;
314
+}
315
+
224 316
 void
225 317
 show_available_tls_ciphers ()
226 318
 {