From abf90e447d26b55cb79b1476ee78600b2ef70609 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Mon, 25 Mar 2019 11:52:55 +0200 Subject: strongSwan module --- aconf/modules/strongswan.lua | 192 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 aconf/modules/strongswan.lua (limited to 'aconf') diff --git a/aconf/modules/strongswan.lua b/aconf/modules/strongswan.lua new file mode 100644 index 0000000..f1c9e08 --- /dev/null +++ b/aconf/modules/strongswan.lua @@ -0,0 +1,192 @@ +--[[ +Copyright (c) 2012-2019 Kaarle Ritvanen +See LICENSE file for license details +--]] + +local M = require('aconf.model') +local util = require('aconf.util') + +local cipher_suites + +local function combine(ciphers, ...) + if not ciphers then return {{{}, {}}} end + + local res = {} + for _, a in ipairs(cipher_suites(ciphers)) do + for _, b in ipairs(combine(...)) do + local c = {} + for i=1,2 do + c[i] = {a[i]} + util.extend(c[i], b[i]) + end + table.insert(res, c) + end + end + return res +end + +function cipher_suites(ciphers) + local res = {} + for _, cs in ipairs(ciphers) do + if type(cs) ~= 'table' then cs = {cs} end + if #cs < 3 then table.insert(res, {cs[1], cs[2] or cs[1]}) + else + local variants = {} + for i=3,#cs do table.insert(variants, cs[i]) end + for _, c in ipairs(combine(table.unpack(variants))) do + table.insert( + res, + { + cs[1]:format(table.unpack(c[1])), + cs[2]:format(table.unpack(c[2])) + } + ) + end + end + end + return res +end + +local Connection = M.new() +Connection.esp_proposals = M.List{ + type=M.List{ + type=M.String{ + choice=cipher_suites{ + {'null', 'No encryption'}, + {'3des', '168-bit 3DES-EDE-CBC'}, + {'cast128', '128-bit CAST-CBC'}, + {'blowfish%d', '%d-bit Blowfish-CBC', {128, 192, 256}}, + { + 'aes%d%s', + '%d-bit AES-%s', + {128, 192, 256}, + { + {'', 'CBC'}, + {'ctr', 'CTR'}, + { + '%s%d', + '%s with %d-bit ICV', + {{'ccm', 'CCM'}, {'gcm', 'GCM'}}, + {{8, 64}, {12, 96}, {16, 128}} + }, + {'gmac', 'GMAC (no encryption)'} + } + }, + { + 'camellia%d%s', + '%d-bit Camellia-%s', + {128, 192, 256}, + { + {'', 'CBC'}, + {'ctr', 'CTR'}, + { + 'ccm%d', + 'CCM with %d-bit ICV', + {{8, 64}, {12, 96}, {16, 128}} + } + } + }, + {'chacha20poly1305', '256-bit ChaCha20/Poly1305 with 128-bit ICV'}, + {'md5%s', '%d-bit HMAC-MD5', {{'', 96}, {'_128', 128}}}, + {'sha1%s', '%d-bit HMAC-SHA1', {{'', 96}, {'_160', 160}}}, + {'aes%s', '96-bit AES-%s', {{'xcbc', 'XCBC'}, {'cmac', 'CMAC'}}}, + {'sha256%s', '%d-bit HMAC-SHA256', {{'_96', 96}, {'', 128}}}, + {'sha384', '192-bit HMAC-SHA384'}, + {'sha512', '256-bit HMAC-SHA512'}, + { + 'prf%s', + '%s PRF', + { + {'md5', 'MD5'}, + {'sha1', 'SHA1'}, + {'aes%s', 'AES-%s', {{'xcbc', 'XCBC'}, {'cmac', 'CMAC'}}}, + {'sha%d', 'SHA%d', {256, 384, 512}} + } + }, + { + 'modp%d', + '%d-bit modulo prime group', + {768, 1024, 1536, 2048, 3072, 4096, 6144, 8192} + }, + { + 'modp1024s160', + '1024-bit group with 160-bit prime order subgroup' + }, + { + 'modp2048s%d', + '2048-bit group with %d-bit prime order subgroup', + {224, 256} + }, + { + 'ecp%d', + '%d-bit NIST elliptic curve group', + {192, 224, 256, 384, 521} + }, + { + 'ecp%dbp', + '%d-bit Brainpool elliptic curve group', + {224, 256, 384, 512} + }, + {'curve25519', '256-bit elliptic curve 25519'}, + {'curve448', '448-bit elliptic curve 25519'}, + { + 'ntru%d', + '%d-bit post-quantum key exchange using NTRU encryption', + {112, 128, 192, 256} + }, + {'newhope128', '128-bit post-quantum key exchange using NewHope'} + } + }, + ui_member='Algorithm' + }, + addr='children/default/#proposals/esp_proposals', + ui_name='ESP proposals', + ui_member='Proposal', + widget='inline' +} +Connection.pools = M.Set{ + type=M.Reference{scope='../../../pools'}, addr='#list/pools' +} + +local Credentials = M.new() +Credentials.priv_keys = M.Collection{ + type=M.String{widget='textarea'}, + addr='private', + ui_name='Private keys', + widget='inline' +} +Credentials.certs = M.Collection{ + type=M.String{widget='textarea'}, + addr='x509', + ui_name='Certificates', + widget='inline' +} +Credentials.ca_certs = M.Collection{ + type=M.String{widget='textarea'}, + addr='x509ca', + ui_name='Authority certificates', + widget='inline' +} + +local Pool = M.new() +Pool.addresses = M.Union{ + types={M.net.IPAddress{cidr=true}, M.Range{type=M.net.IPAddress}}, + required=true, + addr='addrs', + error='Invalid IP address range' +} + +local IPsec = M.service('charon') +IPsec.connections = M.Collection{ + type=M.Model{ + model=Connection, + be_mode={['#list']='value', ['children/default/#proposals']='value'} + } +} +IPsec.credentials = M.Model{model=Credentials, addr='/files/etc/swanctl'} +IPsec.pools = M.Collection{type=Pool} + +M.register( + 'ipsec', IPsec, {addr='/augeas/etc/swanctl/swanctl.conf', ui_name='IPsec'} +) +M.permission.defaults('/ipsec') -- cgit v1.2.3