From 1adf6ab258c0ae577c13359b5019fcb9755ef6a5 Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Sun, 1 Jul 2012 08:58:09 +0000
Subject: [PATCH] add a PKCS#12 file to the zip archive (for quick
 configuration of the android client)

---
 autovpn/vpn_app.py | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/autovpn/vpn_app.py b/autovpn/vpn_app.py
index 62ab73c..5a350ba 100644
--- a/autovpn/vpn_app.py
+++ b/autovpn/vpn_app.py
@@ -2,6 +2,9 @@ import datetime
 import functools
 import logging
 import os
+import shutil
+import subprocess
+import tempfile
 import uuid
 import zipfile
 from cStringIO import StringIO
@@ -105,6 +108,18 @@ The ZIP file contains a configuration for Tunnelblick. Double-click
 on it and it will install itself automatically.
 
 
+Android
+-------
+
+Check out the OpenVPN app at http://code.google.com/p/ics-openvpn/,
+to use it:
+
+- Select the PKCS12 format for the credentials and select the
+  <uuid>.pfx file from the ZIP archive.
+
+- Ensure that LZO compression is disabled.
+
+
 References
 ----------
 
@@ -118,6 +133,24 @@ Further info:
 '''
 
 
+def to_pkcs12(crt_pem, key_pem, ca_pem):
+    """Pack credentials into a PKCS12-format buffer."""
+    tmpdir = tempfile.mkdtemp()
+    try:
+        for name, content in [
+            ('crt.pem', crt_pem), ('key.pem', key_pem), ('ca.pem', ca_pem)]:
+            with open(os.path.join(tmpdir, name)) as fd:
+                fd.write(content)
+        pipe = subprocess.Popen(
+            ['openssl', 'pkcs12', '-export', '-password', 'pass:',
+             '-in', 'crt.pem', '-inkey', 'key.pem',
+             '-CAfile', 'ca.pem'],
+            cwd=tmpdir, stdout=subprocess.PIPE)
+        return pipe.communicate()[0]
+    finally:
+        shutil.rmtree(tmpdir)
+
+
 def csrf(methods=('POST',)):
     def _csrf(fn):
         @functools.wraps(fn)
@@ -214,13 +247,16 @@ def new_cert_dl():
             'vpn_endpoint': current_app.config['VPN_ENDPOINT'],
             'vpn_site': current_app.config['VPN_SITE_URL'],
             'expiry_date': expiry_date.strftime('%Y/%m/%d')}
+    ca_pem = g.ca.get_ca()
     crt_pem = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
     key_pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
+    pkcs12 = to_pkcs12(crt_pem, key_pem, ca_pem)
     manifest = [
-        ('ca.crt', g.ca.get_ca()),
+        ('ca.crt', ca_pem),
         ('crl.pem', g.ca.get_crl(format='pem')),
         ('%s.crt' % cn, crt_pem),
         ('%s.key' % cn, key_pem),
+        ('%s.pfx' % cn, pkcs12),
         ('openvpn-%s.conf' % cn, OPENVPN_CONFIG_TEMPLATE % vars),
         ('README.txt', README_TEMPLATE % vars),
 
-- 
GitLab