util/sasl/scram.lua

Sat, 22 May 2010 01:48:31 +0200

author
Tobias Markmann <tm@ayena.de>
date
Sat, 22 May 2010 01:48:31 +0200
changeset 3099
2c4d06e7e3d3
parent 3098
e5d349c0acde
child 3100
6731dff05c99
permissions
-rw-r--r--

util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)

2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
1 -- sasl.lua v0.4
3094
5f625411b463 util.sasl: 2009 -> 2010 in copyright header.
Tobias Markmann <tm@ayena.de>
parents: 2648
diff changeset
2 -- Copyright (C) 2008-2010 Tobias Markmann
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
3 --
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
4 -- All rights reserved.
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
5 --
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
6 -- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
7 --
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
8 -- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
9 -- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
10 -- * Neither the name of Tobias Markmann nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
11 --
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
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.
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
13
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
14 local s_match = string.match;
2194
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
15 local type = type
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
16 local string = string
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
17 local base64 = require "util.encodings".base64;
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
18 local hmac_sha1 = require "util.hmac".sha1;
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
19 local sha1 = require "util.hashes".sha1;
2192
614c839c30c5 Completed SCRAM-SHA-1 implementation to a ready-to-test state.
Tobias Markmann <tm@ayena.de>
parents: 2190
diff changeset
20 local generate_uuid = require "util.uuid".generate;
2195
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2194
diff changeset
21 local saslprep = require "util.encodings".stringprep.saslprep;
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2194
diff changeset
22 local log = require "util.logger".init("sasl");
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
23 local t_concat = table.concat;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
24 local char = string.char;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
25 local byte = string.byte;
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
26
2202
Tobias Markmann <tm@ayena.de>
parents: 2201
diff changeset
27 module "scram"
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
28
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
29 --=========================
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
30 --SASL SCRAM-SHA-1 according to draft-ietf-sasl-scram-10
3097
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
31
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
32 --[[
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
33 Supported Authentication Backends
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
34
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
35 scram-{MECH}:
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
36 function(username, realm)
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
37 return salted_password, iteration_count, salt, state;
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
38 end
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
39 ]]
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
40
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
41 local default_i = 4096
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
42
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
43 local function bp( b )
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
44 local result = ""
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
45 for i=1, b:len() do
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
46 result = result.."\\"..b:byte(i)
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
47 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
48 return result
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
49 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
50
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
51 local xor_map = {0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;1;0;3;2;5;4;7;6;9;8;11;10;13;12;15;14;2;3;0;1;6;7;4;5;10;11;8;9;14;15;12;13;3;2;1;0;7;6;5;4;11;10;9;8;15;14;13;12;4;5;6;7;0;1;2;3;12;13;14;15;8;9;10;11;5;4;7;6;1;0;3;2;13;12;15;14;9;8;11;10;6;7;4;5;2;3;0;1;14;15;12;13;10;11;8;9;7;6;5;4;3;2;1;0;15;14;13;12;11;10;9;8;8;9;10;11;12;13;14;15;0;1;2;3;4;5;6;7;9;8;11;10;13;12;15;14;1;0;3;2;5;4;7;6;10;11;8;9;14;15;12;13;2;3;0;1;6;7;4;5;11;10;9;8;15;14;13;12;3;2;1;0;7;6;5;4;12;13;14;15;8;9;10;11;4;5;6;7;0;1;2;3;13;12;15;14;9;8;11;10;5;4;7;6;1;0;3;2;14;15;12;13;10;11;8;9;6;7;4;5;2;3;0;1;15;14;13;12;11;10;9;8;7;6;5;4;3;2;1;0;};
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
52
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
53 local result = {};
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
54 local function binaryXOR( a, b )
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
55 for i=1, #a do
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
56 local x, y = byte(a, i), byte(b, i);
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
57 local lowx, lowy = x % 16, y % 16;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
58 local hix, hiy = (x - lowx) / 16, (y - lowy) / 16;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
59 local lowr, hir = xor_map[lowx * 16 + lowy + 1], xor_map[hix * 16 + hiy + 1];
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
60 local r = hir * 16 + lowr;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
61 result[i] = char(r)
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
62 end
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2288
diff changeset
63 return t_concat(result);
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
64 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
65
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
66 -- hash algorithm independent Hi(PBKDF2) implementation
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
67 local function Hi(hmac, str, salt, i)
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
68 local Ust = hmac(str, salt.."\0\0\0\1");
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
69 local res = Ust;
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
70 for n=1,i-1 do
2255
92e329e1cd99 Make some more variables to locals.
Tobias Markmann <tm@ayena.de>
parents: 2206
diff changeset
71 local Und = hmac(str, Ust)
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
72 res = binaryXOR(res, Und)
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
73 Ust = Und
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
74 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
75 return res
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
76 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
77
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
78 local function validate_username(username)
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
79 -- check for forbidden char sequences
2194
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
80 for eq in username:gmatch("=(.?.?)") do
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
81 if eq ~= "2D" and eq ~= "3D" then
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
82 return false
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
83 end
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
84 end
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2193
diff changeset
85
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
86 -- replace =2D with , and =3D with =
2265
7fe644057dc2 util.sasl.scram: Making =2D and =3D substitution actually work.
Tobias Markmann <tm@ayena.de>
parents: 2255
diff changeset
87 username = username:gsub("=2D", ",");
7fe644057dc2 util.sasl.scram: Making =2D and =3D substitution actually work.
Tobias Markmann <tm@ayena.de>
parents: 2255
diff changeset
88 username = username:gsub("=3D", "=");
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
89
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
90 -- apply SASLprep
2195
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2194
diff changeset
91 username = saslprep(username);
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
92 return username;
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
93 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
94
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
95 local function scram_gen(hash_name, H_f, HMAC_f)
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
96 local function scram_hash(self, message)
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
97 if not self.state then self["state"] = {} end
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
98
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
99 if not self.state.name then
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
100 -- we are processing client_first_message
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
101 local client_first_message = message;
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
102
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
103 -- TODO: more strict parsing of client_first_message
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
104 -- TODO: fail if authzid is provided, since we don't support them yet
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
105 self.state["client_first_message"] = client_first_message;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
106 self.state["name"] = client_first_message:match("n=(.+),r=")
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
107 self.state["clientnonce"] = client_first_message:match("r=([^,]+)")
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
108 self.state["gs2_cbind_flag"] = client_first_message:sub(1, 1)
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
109 -- we don't do any channel binding yet
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
110 if self.state.gs2_cbind_flag ~= "n" and self.state.gs2_cbind_flag ~= "y" then
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
111 return "failure", "malformed-request";
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
112 end
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
113
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
114 if not self.state.name or not self.state.clientnonce then
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
115 return "failure", "malformed-request", "Channel binding isn't support at this time.";
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
116 end
2195
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2194
diff changeset
117
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
118 self.state.name = validate_username(self.state.name);
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
119 if not self.state.name then
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
120 log("debug", "Username violates either SASLprep or contains forbidden character sequences.")
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
121 return "failure", "malformed-request", "Invalid username.";
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
122 end
2192
614c839c30c5 Completed SCRAM-SHA-1 implementation to a ready-to-test state.
Tobias Markmann <tm@ayena.de>
parents: 2190
diff changeset
123
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
124 self.state["servernonce"] = generate_uuid();
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
125
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
126 -- retreive credentials
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
127 if self.profile.plain then
3098
e5d349c0acde util.sasl.scram: Fixed global access.
Waqas Hussain <waqas20@gmail.com>
parents: 3097
diff changeset
128 local password, state = self.profile.plain(self.state.name, self.realm)
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
129 if state == nil then return "failure", "not-authorized"
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
130 elseif state == false then return "failure", "account-disabled" end
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
131
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
132 password = saslprep(password);
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
133 if not password then
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
134 log("debug", "Password violates SASLprep.");
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
135 return "failure", "not-authorized", "Invalid password."
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
136 end
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
137 self.state.salt = generate_uuid();
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
138 self.state.iteration_count = default_i;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
139 self.state.salted_password = Hi(HMAC_f, password, self.state.salt, default_i);
3098
e5d349c0acde util.sasl.scram: Fixed global access.
Waqas Hussain <waqas20@gmail.com>
parents: 3097
diff changeset
140 elseif self.profile["scram_"..hash_name] then
e5d349c0acde util.sasl.scram: Fixed global access.
Waqas Hussain <waqas20@gmail.com>
parents: 3097
diff changeset
141 local salted_password, iteration_count, salt, state = self.profile["scram-"..hash_name](self.state.name, self.realm);
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
142 if state == nil then return "failure", "not-authorized"
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
143 elseif state == false then return "failure", "account-disabled" end
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
144
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
145 self.state.salted_password = salted_password;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
146 self.state.iteration_count = iteration_count;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
147 self.state.salt = salt
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
148 end
2192
614c839c30c5 Completed SCRAM-SHA-1 implementation to a ready-to-test state.
Tobias Markmann <tm@ayena.de>
parents: 2190
diff changeset
149
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
150 local server_first_message = "r="..self.state.clientnonce..self.state.servernonce..",s="..base64.encode(self.state.salt)..",i="..self.state.iteration_count;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
151 self.state["server_first_message"] = server_first_message;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
152 return "challenge", server_first_message
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
153 else
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
154 if type(message) ~= "string" then return "failure", "malformed-request" end
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
155 -- we are processing client_final_message
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
156 local client_final_message = message;
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
157
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
158 -- TODO: more strict parsing of client_final_message
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
159 self.state["proof"] = client_final_message:match("p=(.+)");
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
160 self.state["nonce"] = client_final_message:match("r=(.+),p=");
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
161 self.state["channelbinding"] = client_final_message:match("c=(.+),r=");
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
162
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
163 if not self.state.proof or not self.state.nonce or not self.state.channelbinding then
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
164 return "failure", "malformed-request", "Missing an attribute(p, r or c) in SASL message.";
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
165 end
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
166
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
167 if self.state.nonce ~= self.state.servernonce then
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
168 return "failure", "malformed-request", "Wrong nonce in client-second-message.";
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
169 end
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
170
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
171 local SaltedPassword = self.state.salted_password;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
172 local ClientKey = HMAC_f(SaltedPassword, "Client Key")
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
173 local ServerKey = HMAC_f(SaltedPassword, "Server Key")
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
174 local StoredKey = H_f(ClientKey)
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
175 local AuthMessage = "n=" .. s_match(self.state.client_first_message,"n=(.+)") .. "," .. self.state.server_first_message .. "," .. s_match(client_final_message, "(.+),p=.+")
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
176 local ClientSignature = HMAC_f(StoredKey, AuthMessage)
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
177 local ClientProof = binaryXOR(ClientKey, ClientSignature)
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
178 local ServerSignature = HMAC_f(ServerKey, AuthMessage)
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
179
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
180 if base64.encode(ClientProof) == self.state.proof then
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
181 local server_final_message = "v="..base64.encode(ServerSignature);
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
182 self["username"] = self.state.name;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
183 return "success", server_final_message;
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
184 else
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
185 return "failure", "not-authorized", "The response provided by the client doesn't match the one we calculated.";
2195
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2194
diff changeset
186 end
2192
614c839c30c5 Completed SCRAM-SHA-1 implementation to a ready-to-test state.
Tobias Markmann <tm@ayena.de>
parents: 2190
diff changeset
187 end
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
188 end
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
189 return scram_hash;
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
190 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
191
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
192 function init(registerMechanism)
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
193 local function registerSCRAMMechanism(hash_name, hash, hmac_hash)
3098
e5d349c0acde util.sasl.scram: Fixed global access.
Waqas Hussain <waqas20@gmail.com>
parents: 3097
diff changeset
194 registerMechanism("SCRAM-"..hash_name, {"plain", "scram_"..(hash_name:lower())}, scram_gen(hash_name:lower(), hash, hmac_hash));
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
195 end
3099
2c4d06e7e3d3 util.sasl.scram: Check nonce in client final message. Check channel binding flag in client first message. Adding some TODOs on more strict parsing. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3098
diff changeset
196
3096
e69282792686 util.sasl: Abstracting out the hash function used since SCRAM is independent of it. Adding scram-{mech} authentication backend support.
Tobias Markmann <tm@ayena.de>
parents: 3094
diff changeset
197 registerSCRAMMechanism("SHA-1", sha1, hmac_sha1);
2190
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
198 end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
199
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
200 return _M;

mercurial