-
Notifications
You must be signed in to change notification settings - Fork 3
/
dmvpn-pfx-decode
executable file
·97 lines (86 loc) · 2.22 KB
/
dmvpn-pfx-decode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/lua5.2
--[[
Copyright (c) 2017-2018 Kaarle Ritvanen
See LICENSE file for license details
]]--
dmvpn = require('dmvpn')
pkcs12 = require('openssl.pkcs12')
rfc5280 = require('asn1.rfc5280')
name = arg[1]
file = io.open(name)
data = file:read('*a')
file:close()
name = name:match('/([^/]+)$') or name
password = name:match('^[-%w]*_%d+%.(%w+)%.pfx$')
if password then
success, key, cert, chain = pcall(pkcs12.parse, data, password)
end
if not success then
key, cert, chain = pkcs12.parse(data, dmvpn.get_password())
end
function write_pem_file(data, dir, suffix)
local file = io.open(
'/etc/swanctl/'..dir..'/dmvpn'..(suffix or '')..'.pem', 'w'
)
file:write(data)
file:close()
end
write_pem_file(key:toPEM('private'), 'private')
write_pem_file(tostring(cert), 'x509')
for _, ca_cert in pairs(chain) do
local suffix
local usage = rfc5280.KeyUsage.decode(
ca_cert:getExtension('keyUsage'):getData()
)
if usage.keyCertSign then suffix = ''
elseif usage.cRLSign then suffix = '-crl' end
if suffix then write_pem_file(tostring(ca_cert), 'x509ca', suffix) end
end
function print_var(name, value)
print(name.."='"..value:gsub("'", "'\\''").."'")
end
for tpe, value in pairs(cert:getSubjectAlt()) do
if tpe == 'IP' then
if value:match('^[%d%.]+$') then
print_var('GRE_IPV4_ADDRESS', value)
elseif value:match('^[%x:]+$') then
print_var('GRE_IPV6_ADDRESS', value)
else assert(false) end
end
end
EXTENSIONS = {
basicConstraints=true,
['sbgp-ipAddrBlock']={
IPV4_PREFIXES=function(v) return v[1] end,
IPV6_PREFIXES=function(v) return v[2] end
},
['sbgp-autonomousSysNum']='AS_NUMBER',
[dmvpn.OID_IS_HUB]={
VPNC_TYPE=function(v) return v and 'hub' or 'spoke' end
},
[dmvpn.OID_HUB_HOSTS]='HUBS'
}
for i=1,cert:getExtensionCount() do
ext = cert:getExtension(i)
k = ext:getName()
v = EXTENSIONS[k]
if v then
if type(v) == 'string' then
v = {[v]=function(v) return v end}
end
if type(v) == 'table' then
local data = dmvpn.decode_ext(k, ext)
for var, func in pairs(v) do
local d = func(data)
print_var(
var,
type(d) == 'table' and
table.concat(d, ' ') or
tostring(d)
)
end
end
elseif ext:getCritical() then
error('Unrecognized critical extension: '..k)
end
end