Comparison

util/sasl/scram.lua @ 5844:4f545674b0bc

util.sasl.scram: Simplify validation of client-first-message
author Kim Alvefur <zash@zash.se>
date Sun, 22 Sep 2013 04:29:27 +0200
parent 5843:fb6573e191cf
child 5856:e3e593eb81d1
comparison
equal deleted inserted replaced
5843:fb6573e191cf 5844:4f545674b0bc
11 -- 11 --
12 -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13 13
14 local s_match = string.match; 14 local s_match = string.match;
15 local type = type 15 local type = type
16 local string = string
17 local tostring = tostring; 16 local tostring = tostring;
18 local base64 = require "util.encodings".base64; 17 local base64 = require "util.encodings".base64;
19 local hmac_sha1 = require "util.hashes".hmac_sha1; 18 local hmac_sha1 = require "util.hashes".hmac_sha1;
20 local sha1 = require "util.hashes".sha1; 19 local sha1 = require "util.hashes".sha1;
21 local Hi = require "util.hashes".scram_Hi_sha1; 20 local Hi = require "util.hashes".scram_Hi_sha1;
122 local client_first_message = message; 121 local client_first_message = message;
123 122
124 -- TODO: fail if authzid is provided, since we don't support them yet 123 -- TODO: fail if authzid is provided, since we don't support them yet
125 self.state["client_first_message"] = client_first_message; 124 self.state["client_first_message"] = client_first_message;
126 self.state["gs2_cbind_flag"], self.state["gs2_cbind_name"], self.state["authzid"], self.state["name"], self.state["clientnonce"] 125 self.state["gs2_cbind_flag"], self.state["gs2_cbind_name"], self.state["authzid"], self.state["name"], self.state["clientnonce"]
127 = client_first_message:match("^(%a)=?([%a%-]*),(.*),n=(.*),r=([^,]*).*"); 126 = client_first_message:match("^([ynp])=?([%a%-]*),(.*),n=(.*),r=([^,]*).*");
128 127
129 -- check for invalid gs2_flag_type start 128 local gs2_cbind_flag = self.state.gs2_cbind_flag;
130 local gs2_flag_type = string.sub(self.state.gs2_cbind_flag, 0, 1) 129
131 if gs2_flag_type ~= "y" and gs2_flag_type ~= "n" and gs2_flag_type ~= "p" then 130 if not gs2_cbind_flag then
132 return "failure", "malformed-request", "The GS2 header has to start with 'y', 'n', or 'p'." 131 return "failure", "malformed-request";
133 end 132 end
134 133
135 if support_channel_binding then 134 if support_channel_binding and gs2_cbind_flag == "y" then
136 if string.sub(self.state.gs2_cbind_flag, 0, 1) == "y" then 135 -- "y" -> client does support channel binding
136 -- but thinks the server does not.
137 return "failure", "malformed-request"; 137 return "failure", "malformed-request";
138 end 138 end
139 139
140 if gs2_cbind_flag == "n" then
141 -- "n" -> client doesn't support channel binding.
142 support_channel_binding = false;
143 end
144
145 if support_channel_binding and gs2_cbind_flag == "p" then
140 -- check whether we support the proposed channel binding type 146 -- check whether we support the proposed channel binding type
141 if not self.profile.cb[self.state.gs2_cbind_name] then 147 if not self.profile.cb[self.state.gs2_cbind_name] then
142 return "failure", "malformed-request", "Proposed channel binding type isn't supported."; 148 return "failure", "malformed-request", "Proposed channel binding type isn't supported.";
143 end 149 end
144 else 150 else
145 -- we don't support channelbinding, 151 -- no channel binding,
146 if self.state.gs2_cbind_flag ~= "n" and self.state.gs2_cbind_flag ~= "y" then 152 self.state.gs2_cbind_name = nil;
147 return "failure", "malformed-request";
148 end
149 end 153 end
150 154
151 if not self.state.name or not self.state.clientnonce then 155 if not self.state.name or not self.state.clientnonce then
152 return "failure", "malformed-request", "Channel binding isn't support at this time."; 156 return "failure", "malformed-request", "Channel binding isn't support at this time.";
153 end 157 end
240 end 244 end
241 245
242 function init(registerMechanism) 246 function init(registerMechanism)
243 local function registerSCRAMMechanism(hash_name, hash, hmac_hash) 247 local function registerSCRAMMechanism(hash_name, hash, hmac_hash)
244 registerMechanism("SCRAM-"..hash_name, {"plain", "scram_"..(hashprep(hash_name))}, scram_gen(hash_name:lower(), hash, hmac_hash)); 248 registerMechanism("SCRAM-"..hash_name, {"plain", "scram_"..(hashprep(hash_name))}, scram_gen(hash_name:lower(), hash, hmac_hash));
245 249
246 -- register channel binding equivalent 250 -- register channel binding equivalent
247 registerMechanism("SCRAM-"..hash_name.."-PLUS", {"plain", "scram_"..(hashprep(hash_name))}, scram_gen(hash_name:lower(), hash, hmac_hash), {"tls-unique"}); 251 registerMechanism("SCRAM-"..hash_name.."-PLUS", {"plain", "scram_"..(hashprep(hash_name))}, scram_gen(hash_name:lower(), hash, hmac_hash), {"tls-unique"});
248 end 252 end
249 253
250 registerSCRAMMechanism("SHA-1", sha1, hmac_sha1); 254 registerSCRAMMechanism("SHA-1", sha1, hmac_sha1);