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 |