diff -r -u openvpn-2.0_beta7/init.c openvpn-2.0_beta7-pkcs12/init.c
--- openvpn-2.0_beta7/init.c	2004-06-29 15:24:36.000000000 +0200
+++ openvpn-2.0_beta7-pkcs12/init.c	2004-07-10 09:30:19.000000000 +0200
@@ -891,6 +891,7 @@
 				   options->dh_file,
 				   options->cert_file,
 				   options->priv_key_file,
+				   options->pkcs12_file,
 				   options->cipher_list);
 
       /* Get cipher & hash algorithms */
diff -r -u openvpn-2.0_beta7/options.c openvpn-2.0_beta7-pkcs12/options.c
--- openvpn-2.0_beta7/options.c	2004-06-29 11:31:02.000000000 +0200
+++ openvpn-2.0_beta7-pkcs12/options.c	2004-07-10 09:23:54.000000000 +0200
@@ -312,6 +312,8 @@
   "--cert file     : Local certificate in .pem format -- must be signed\n"
   "                  by a Certificate Authority in --ca file.\n"
   "--key file      : Local private key in .pem format.\n"
+  "--pkcs12 file   : PKCS#12 file containing local private key, local certificate\n"
+  "                  and root CA certificate.\n" 
   "--tls-cipher l  : A list l of allowable TLS ciphers separated by : (optional).\n"
   "                : Use --show-tls to see a list of supported TLS ciphers.\n"
   "--tls-timeout n : Packet retransmit timeout on TLS control channel\n"
@@ -838,6 +840,7 @@
   SHOW_STR (dh_file);
   SHOW_STR (cert_file);
   SHOW_STR (priv_key_file);
+  SHOW_STR (pkcs12_file);
   SHOW_STR (cipher_list);
   SHOW_STR (tls_verify);
   SHOW_STR (tls_remote);
@@ -1160,9 +1163,21 @@
     }
   if (options->tls_server || options->tls_client)
     {
-      notnull (options->ca_file, "CA file (--ca)");
-      notnull (options->cert_file, "certificate file (--cert)");
-      notnull (options->priv_key_file, "private key file (--key)");
+      if (options->pkcs12_file)
+        {
+          if (options->ca_file) 
+	    msg(M_USAGE, "Options error: Parameter --ca can not be used when --pkcs12 is also specified.");
+          if (options->cert_file) 
+	    msg(M_USAGE, "Options error: Parameter --cert can not be used when --pkcs12 is also specified.");
+          if (options->priv_key_file) 
+	    msg(M_USAGE, "Options error: Parameter --key can not be used when --pkcs12 is also specified.");
+        }
+      else
+        {
+          notnull (options->ca_file, "CA file (--ca) or PKCS#12 file (--pkcs12)");
+          notnull (options->cert_file, "certificate file (--cert) or PKCS#12 file (--pkcs12)");
+          notnull (options->priv_key_file, "private key file (--key) or PKCS#12 file (--pkcs12)");
+	}
       if (first_time && options->askpass)
 	pem_password_callback (NULL, 0, 0, NULL);
     }
@@ -1181,6 +1196,7 @@
       MUST_BE_UNDEF (dh_file);
       MUST_BE_UNDEF (cert_file);
       MUST_BE_UNDEF (priv_key_file);
+      MUST_BE_UNDEF (pkcs12_file);
       MUST_BE_UNDEF (cipher_list);
       MUST_BE_UNDEF (tls_verify);
       MUST_BE_UNDEF (tls_remote);
@@ -3025,6 +3041,12 @@
       VERIFY_PERMISSION (OPT_P_GENERAL);
       options->priv_key_file = p[1];
     }
+  else if (streq (p[0], "pkcs12") && p[1])
+    {
+      ++i;
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->pkcs12_file = p[1];
+    }
   else if (streq (p[0], "askpass"))
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
diff -r -u openvpn-2.0_beta7/options.h openvpn-2.0_beta7-pkcs12/options.h
--- openvpn-2.0_beta7/options.h	2004-06-27 08:20:04.000000000 +0200
+++ openvpn-2.0_beta7-pkcs12/options.h	2004-07-10 08:35:42.000000000 +0200
@@ -272,6 +272,7 @@
   const char *dh_file;
   const char *cert_file;
   const char *priv_key_file;
+  const char *pkcs12_file;
   const char *cipher_list;
   const char *tls_verify;
   const char *tls_remote;
diff -r -u openvpn-2.0_beta7/ssl.c openvpn-2.0_beta7-pkcs12/ssl.c
--- openvpn-2.0_beta7/ssl.c	2004-06-29 14:42:57.000000000 +0200
+++ openvpn-2.0_beta7-pkcs12/ssl.c	2004-07-10 14:27:05.000000000 +0200
@@ -573,6 +573,7 @@
 	  const char *dh_file,
 	  const char *cert_file,
 	  const char *priv_key_file,
+	  const char *pkcs12_file,
 	  const char *cipher_list)
 {
   SSL_CTX *ctx;
@@ -614,35 +615,96 @@
   /* Set callback for getting password from user to decrypt private key */
   SSL_CTX_set_default_passwd_cb (ctx, pem_password_callback);
 
-  /* Load Certificate */
-  if (!SSL_CTX_use_certificate_file (ctx, cert_file, SSL_FILETYPE_PEM))
-    msg (M_SSLERR, "Cannot load certificate file %s", cert_file);
-
-  /* Load Private Key */
-  if (!SSL_CTX_use_PrivateKey_file (ctx, priv_key_file, SSL_FILETYPE_PEM))
-    msg (M_SSLERR, "Cannot load private key file %s", priv_key_file);
-  warn_if_group_others_accessible (priv_key_file);
-
-  /* Check Private Key */
-  if (!SSL_CTX_check_private_key (ctx))
-    msg (M_SSLERR, "Private key does not match the certificate");
-
-  /* Load CA file for verifying peer supplied certificate */
-  if (!SSL_CTX_load_verify_locations (ctx, ca_file, NULL))
-    msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_CTX_load_verify_locations)", ca_file);
+  if (pkcs12_file)
+    {
+    /* Use PKCS #12 file for key, cert and CA certs */
 
-  /* Load names of CAs from file and use it as a client CA list */
-  {
-    STACK_OF(X509_NAME) *cert_names;
-    cert_names = SSL_load_client_CA_file (ca_file);
-    if (!cert_names)
-      msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", ca_file);
-    SSL_CTX_set_client_CA_list (ctx, cert_names);
-  }
+      FILE *fp;
+      EVP_PKEY *pkey;
+      X509 *cert;
+      STACK_OF(X509) *ca = NULL;
+      PKCS12 *p12;
+      int i;
+      char password[256];
+
+      /* Load the PKCS #12 file */
+      if (!(fp = fopen(pkcs12_file, "rb")))
+        msg (M_SSLERR, "Error opening file %s", pkcs12_file);
+      p12 = d2i_PKCS12_fp(fp, NULL);
+      fclose (fp);
+      if (!p12) msg (M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file);
+      
+      /* Parse the PKCS #12 file */
+      if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
+        {
+          pem_password_callback (password, sizeof(password) - 1, 0, NULL);
+          /* Reparse the PKCS #12 file with password */
+          ca = NULL;
+          if (!PKCS12_parse(p12, password, &pkey, &cert, &ca))
+             msg (M_SSLERR, "Error parsing PKCS#12 file %s", pkcs12_file);
+        }
+      PKCS12_free(p12);
+
+      /* Load Certificate */
+      if (!SSL_CTX_use_certificate (ctx, cert))
+        msg (M_SSLERR, "Cannot use certificate");
+
+      /* Load Private Key */
+      if (!SSL_CTX_use_PrivateKey (ctx, pkey))
+        msg (M_SSLERR, "Cannot use private key");
+      warn_if_group_others_accessible (pkcs12_file);
+
+      /* Check Private Key */
+      if (!SSL_CTX_check_private_key (ctx))
+        msg (M_SSLERR, "Private key does not match the certificate");
+
+      /* Set Certificate Verification chain */
+      if (ca && sk_num(ca))
+        {
+          for (i = 0; i < sk_X509_num(ca); i++)
+            {
+	      if (!X509_STORE_add_cert(ctx->cert_store,sk_X509_value(ca, i)))
+                 msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)");
+              if (!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i)))
+                msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
+            }
+        }
+    }
+  else
+    {
+    /* Use seperate PEM files for key, cert and CA certs */
+
+      /* Load Certificate */
+      if (!SSL_CTX_use_certificate_file (ctx, cert_file, SSL_FILETYPE_PEM))
+        msg (M_SSLERR, "Cannot load certificate file %s", cert_file);
+
+      /* Load Private Key */
+      if (!SSL_CTX_use_PrivateKey_file (ctx, priv_key_file, SSL_FILETYPE_PEM))
+        msg (M_SSLERR, "Cannot load private key file %s", priv_key_file);
+      warn_if_group_others_accessible (priv_key_file);
+
+      /* Check Private Key */
+      if (!SSL_CTX_check_private_key (ctx))
+        msg (M_SSLERR, "Private key does not match the certificate");
+
+      /* Load CA file for verifying peer supplied certificate */
+      if (!SSL_CTX_load_verify_locations (ctx, ca_file, NULL))
+        msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_CTX_load_verify_locations)", ca_file);
+
+      /* Load names of CAs from file and use it as a client CA list */
+      {
+        STACK_OF(X509_NAME) *cert_names;
+        cert_names = SSL_load_client_CA_file (ca_file);
+        if (!cert_names)
+          msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", ca_file);
+        SSL_CTX_set_client_CA_list (ctx, cert_names);
+      }
+
+      /* Enable the use of certificate chains */
+      if (!SSL_CTX_use_certificate_chain_file (ctx, cert_file))
+        msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", cert_file);
+    }
 
-  /* Enable the use of certificate chains */
-  if (!SSL_CTX_use_certificate_chain_file (ctx, cert_file))
-    msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", cert_file);
 
   /* Require peer certificate verification */
   SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
diff -r -u openvpn-2.0_beta7/ssl.h openvpn-2.0_beta7-pkcs12/ssl.h
--- openvpn-2.0_beta7/ssl.h	2004-06-29 14:10:49.000000000 +0200
+++ openvpn-2.0_beta7-pkcs12/ssl.h	2004-07-10 10:03:40.000000000 +0200
@@ -32,6 +32,7 @@
 #include <openssl/bio.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
+#include <openssl/pkcs12.h>
 
 #include "basic.h"
 #include "crypto.h"
@@ -436,6 +437,7 @@
 		   const char *ca_file,
 		   const char *dh_file,
 		   const char *cert_file,
+		   const char *pkcs12_file,
 		   const char *priv_key_file, const char *cipher_list);
 
 struct tls_multi *tls_multi_init (struct tls_options *tls_options);
