Comparison

mod_s2s_auth_dane/mod_s2s_auth_dane.lua @ 1348:6191613959dc

mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
author Kim Alvefur <zash@zash.se>
date Fri, 14 Mar 2014 14:18:18 +0100
parent 1347:52b419885f0a
child 1349:350e903b14ff
comparison
equal deleted inserted replaced
1347:52b419885f0a 1348:6191613959dc
6 -- Could be done much cleaner if mod_s2s was using util.async 6 -- Could be done much cleaner if mod_s2s was using util.async
7 7
8 8
9 module:set_global(); 9 module:set_global();
10 10
11 local type = type;
12 local set = require"util.set";
11 local dns_lookup = require"net.adns".lookup; 13 local dns_lookup = require"net.adns".lookup;
12 local hashes = require"util.hashes"; 14 local hashes = require"util.hashes";
13 local base64 = require"util.encodings".base64; 15 local base64 = require"util.encodings".base64;
14 local idna_to_ascii = require "util.encodings".idna.to_ascii; 16 local idna_to_ascii = require "util.encodings".idna.to_ascii;
15 17
23 local typ, data = pem:match(pat); 25 local typ, data = pem:match(pat);
24 if typ and data then 26 if typ and data then
25 return base64.decode(data), typ; 27 return base64.decode(data), typ;
26 end 28 end
27 end 29 end
30 local use_map = { ["DANE-EE"] = 3; ["DANE-TA"] = 2; ["PKIX-EE"] = 1; ["PKIX-CA"] = 0 }
31
32 local implemented_uses = set.new { "DANE-EE", "PKIX-EE" };
33 local configured_uses = module:get_option_set("dane_uses", { "DANE-EE" });
34 local enabled_uses = set.intersection(implemented_uses, configured_uses) / function(use) return use_map[use] end;
28 35
29 -- TODO Things to test/handle: 36 -- TODO Things to test/handle:
30 -- Negative or bogus answers 37 -- Negative or bogus answers
31 -- No SRV records 38 -- No SRV records
32 -- No encryption offered 39 -- No encryption offered
89 for i = 1, #dane do 96 for i = 1, #dane do
90 tlsa = dane[i].tlsa; 97 tlsa = dane[i].tlsa;
91 module:log("debug", "TLSA %s %s %s %d bytes of data", tlsa:getUsage(), tlsa:getSelector(), tlsa:getMatchType(), #tlsa.data); 98 module:log("debug", "TLSA %s %s %s %d bytes of data", tlsa:getUsage(), tlsa:getSelector(), tlsa:getMatchType(), #tlsa.data);
92 use, select, match, certdata = tlsa.use, tlsa.select, tlsa.match; 99 use, select, match, certdata = tlsa.use, tlsa.select, tlsa.match;
93 100
94 -- PKIX-EE or DANE-EE 101 if enabled_uses:contains(use) then
95 if use == 1 or use == 3 then 102 -- PKIX-EE or DANE-EE
96 supported_found = true 103 if use == 1 or use == 3 then
104 supported_found = true
97 105
98 if select == 0 then 106 if select == 0 then
99 certdata = pem2der(cert:pem()); 107 certdata = pem2der(cert:pem());
100 elseif select == 1 and cert.pubkey then 108 elseif select == 1 and cert.pubkey then
101 certdata = pem2der(cert:pubkey()); -- Not supported in stock LuaSec 109 certdata = pem2der(cert:pubkey()); -- Not supported in stock LuaSec
102 else 110 else
103 module:log("warn", "DANE selector %s is unsupported", tlsa:getSelector() or select); 111 module:log("warn", "DANE selector %s is unsupported", tlsa:getSelector() or select);
104 end 112 end
105 113
106 if match == 1 then 114 if match == 1 then
107 certdata = hashes.sha256(certdata); 115 certdata = hashes.sha256(certdata);
108 elseif match == 2 then 116 elseif match == 2 then
109 certdata = hashes.sha512(certdata); 117 certdata = hashes.sha512(certdata);
110 elseif match ~= 0 then 118 elseif match ~= 0 then
111 module:log("warn", "DANE match rule %s is unsupported", tlsa:getMatchType() or match); 119 module:log("warn", "DANE match rule %s is unsupported", tlsa:getMatchType() or match);
112 certdata = nil; 120 certdata = nil;
113 end 121 end
114 122
115 -- Should we check if the cert subject matches? 123 -- Should we check if the cert subject matches?
116 if certdata and certdata == tlsa.data then 124 if certdata and certdata == tlsa.data then
117 (session.log or module._log)("info", "DANE validation successful"); 125 (session.log or module._log)("info", "DANE validation successful");
118 session.cert_identity_status = "valid"; 126 session.cert_identity_status = "valid";
119 if use == 3 then -- DANE-EE, chain status equals DNSSEC chain status 127 if use == 3 then -- DANE-EE, chain status equals DNSSEC chain status
120 session.cert_chain_status = "valid"; 128 session.cert_chain_status = "valid";
121 -- for usage 1, PKIX-EE, the chain has to be valid already 129 -- for usage 1, PKIX-EE, the chain has to be valid already
130 end
131 match_found = true;
132 break;
122 end 133 end
123 match_found = true;
124 break;
125 end 134 end
126 end 135 end
127 end 136 end
128 if supported_found and not match_found or dane.bogus then 137 if supported_found and not match_found or dane.bogus then
129 -- No TLSA matched or response was bogus 138 -- No TLSA matched or response was bogus