Skip to content

Instantly share code, notes, and snippets.

@carlosmcevilly
Created January 7, 2015 17:46
Show Gist options
  • Select an option

  • Save carlosmcevilly/a04a127b779a0d78b038 to your computer and use it in GitHub Desktop.

Select an option

Save carlosmcevilly/a04a127b779a0d78b038 to your computer and use it in GitHub Desktop.
Given a .pfx and .ovpn file pair, create a new .ovpn file with the key and certs inline, suitable for use with the OpenVPN iOS app.
#!/usr/bin/perl
use strict;
use warnings;
# $Id: make-ios-ovpn.pl,v 0.0 2015/01/07 06:18:40 carlos Exp $
my ($pfxfile, $ovpnfile, $out, $rest) = @ARGV;
error_exit("usage: $0 <pfxfile> <ovpnfile> <out>")
unless (defined($out) && !defined($rest));
error_exit("$0: output file $out already exists") unless (! -e $out);
# parse the certs and key from the .pfx file
my $certsfile = "certs.$$";
print("\n\nYou will be prompted for a password if the .pfx file is encrypted.\n\n");
print("You will then be prompted again to enter an encryption password (twice)\nto protect the key in the new .ovpn file. You'll need to enter that\npassword in the OpenVPN app.\n\n\n");
`openssl pkcs12 -info -in $pfxfile > $certsfile`;
my ($cert,$cacert,$key) = @{&parse_certsfile($certsfile)};
unlink($certsfile);
# read the .ovpn file and create an edited copy of it in the output file
open(OVPN, $ovpnfile) or die "unable to open file $ovpnfile for input";
open(OUT, ">$out") or die "unable to open file $out for output";
while (my $line=<OVPN>) {
chomp($line);
$line =~ s/^\s*(.*?)\s*$/$1/;
if ($line =~ m{^pkcs12\s+\w+.pfx}) {
print OUT "#$line\n";
print OUT "<ca>\n$cacert\n</ca>\n";
print OUT "<cert>\n$cert\n</cert>\n";
print OUT "<key>\n$key\n</key>\n";
} else {
print OUT "$line\n";
}
}
close(OUT);
close(OVPN);
####################################################
sub parse_certsfile() {
my $certsfile = shift;
open(CERTS, $certsfile) or
die "unable to open file $certsfile for input";
local $/;
my $certs = <CERTS>;
close(CERTS);
my $begincert = "-----BEGIN CERTIFICATE-----";
my $endcert = "-----END CERTIFICATE-----";
my $beginkey = "-----BEGIN RSA PRIVATE KEY-----";
my $endkey = "-----END RSA PRIVATE KEY-----";
my ($cert,$cacert,$key);
if ($certs =~ m{subject=/CN=.*?($begincert.*?$endcert).*}s) {
$cert = $1;
}
if ($certs =~ m{subject=/OU=.*?($begincert.*?$endcert).*}s) {
$cacert = $1;
}
if ($certs =~ m{($beginkey.*?$endkey)}s) {
$key = $1;
}
return [$cert,$cacert,$key];
}
sub error_exit {
my $message = shift;
if (defined($message)) {
print STDERR "$message\n";
}
exit(-1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment