mod_s2s_auth_dane/mod_s2s_auth_dane.lua
changeset 1389 6bd9681d54b7
parent 1383 465e5d79551b
child 1390 1fcd280c226b
equal deleted inserted replaced
1388:6e1facedcb74 1389:6bd9681d54b7
   137 			return false;
   137 			return false;
   138 		end
   138 		end
   139 	end);
   139 	end);
   140 end
   140 end
   141 
   141 
       
   142 local function one_dane_check(tlsa, cert)
       
   143 	local select, match, certdata = tlsa.select, tlsa.match;
       
   144 
       
   145 	if select == 0 then
       
   146 		certdata = pem2der(cert:pem());
       
   147 	elseif select == 1 and cert.pubkey then
       
   148 		certdata = pem2der(cert:pubkey());
       
   149 	else
       
   150 		module:log("warn", "DANE selector %s is unsupported", tlsa:getSelector() or select);
       
   151 		return;
       
   152 	end
       
   153 
       
   154 	if match == 1 then
       
   155 		certdata = hashes.sha256(certdata);
       
   156 	elseif match == 2 then
       
   157 		certdata = hashes.sha512(certdata);
       
   158 	elseif match ~= 0 then
       
   159 		module:log("warn", "DANE match rule %s is unsupported", tlsa:getMatchType() or match);
       
   160 		return;
       
   161 	end
       
   162 
       
   163 	return certdata == tlsa.data;
       
   164 end
       
   165 
   142 module:hook("s2s-check-certificate", function(event)
   166 module:hook("s2s-check-certificate", function(event)
   143 	local session, cert = event.session, event.cert;
   167 	local session, cert = event.session, event.cert;
   144 	local dane = session.dane;
   168 	local dane = session.dane;
   145 	if type(dane) == "table" then
   169 	if type(dane) == "table" then
   146 		local use, select, match, tlsa, certdata, match_found, supported_found;
   170 		local use, tlsa, match_found, supported_found, is_match;
   147 		for i = 1, #dane do
   171 		for i = 1, #dane do
   148 			tlsa = dane[i].tlsa;
   172 			tlsa = dane[i].tlsa;
   149 			module:log("debug", "TLSA %s %s %s %d bytes of data", tlsa:getUsage(), tlsa:getSelector(), tlsa:getMatchType(), #tlsa.data);
   173 			module:log("debug", "TLSA %s %s %s %d bytes of data", tlsa:getUsage(), tlsa:getSelector(), tlsa:getMatchType(), #tlsa.data);
   150 			use, select, match, certdata = tlsa.use, tlsa.select, tlsa.match;
   174 			use = tlsa.use;
   151 
   175 
   152 			if enabled_uses:contains(use) then
   176 			if enabled_uses:contains(use) then
   153 				-- PKIX-EE or DANE-EE
   177 				-- PKIX-EE or DANE-EE
   154 				if use == 1 or use == 3 then
   178 				if use == 1 or use == 3 then
   155 					supported_found = true
   179 					-- Should we check if the cert subject matches?
   156 
   180 					is_match = one_dane_check(tlsa, cert);
   157 					if select == 0 then
   181 					if is_match ~= nil then
   158 						certdata = pem2der(cert:pem());
   182 						supported_found = true;
   159 					elseif select == 1 and cert.pubkey then
       
   160 						certdata = pem2der(cert:pubkey()); -- Not supported in stock LuaSec
       
   161 					else
       
   162 						module:log("warn", "DANE selector %s is unsupported", tlsa:getSelector() or select);
       
   163 					end
   183 					end
   164 
   184 					if is_match then
   165 					if match == 1 then
       
   166 						certdata = certdata and hashes.sha256(certdata);
       
   167 					elseif match == 2 then
       
   168 						certdata = certdata and hashes.sha512(certdata);
       
   169 					elseif match ~= 0 then
       
   170 						module:log("warn", "DANE match rule %s is unsupported", tlsa:getMatchType() or match);
       
   171 						certdata = nil;
       
   172 					end
       
   173 
       
   174 					-- Should we check if the cert subject matches?
       
   175 					if certdata and certdata == tlsa.data then
       
   176 						(session.log or module._log)("info", "DANE validation successful");
   185 						(session.log or module._log)("info", "DANE validation successful");
   177 						session.cert_identity_status = "valid";
   186 						session.cert_identity_status = "valid";
   178 						if use == 3 then -- DANE-EE, chain status equals DNSSEC chain status
   187 						if use == 3 then -- DANE-EE, chain status equals DNSSEC chain status
   179 							session.cert_chain_status = "valid";
   188 							session.cert_chain_status = "valid";
   180 							-- for usage 1, PKIX-EE, the chain has to be valid already
   189 							-- for usage 1, PKIX-EE, the chain has to be valid already