util/sasl/scram.lua
author Kim Alvefur <zash@zash.se>
Fri, 21 Sep 2018 21:19:44 +0200
changeset 9339 9e8d7d461c7d
parent 8731 41c959c5c84b
child 10220 a51d017e6173
child 10916 646af16a3f32
permissions -rw-r--r--
mod_http: Hook the host-less event if hooked from a global module
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2194
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
2194
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.
2194
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:
2194
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.
2194
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.
2194
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;
2198
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2197
diff changeset
    15
local type = type
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    16
local base64 = require "util.encodings".base64;
5537
15464633d8fb util.hmac, util.hashes: Implement HMAC functions in C, and move to util.hashes
Florian Zeitz <florob@babelmonkeys.de>
parents: 5301
diff changeset
    17
local hmac_sha1 = require "util.hashes".hmac_sha1;
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    18
local sha1 = require "util.hashes".sha1;
5538
62089c9c142d util.hashes, util.sasl.scram: Implement SCRAM-SHA1's Hi in C
Florian Zeitz <florob@babelmonkeys.de>
parents: 5537
diff changeset
    19
local Hi = require "util.hashes".scram_Hi_sha1;
2196
614c839c30c5 Completed SCRAM-SHA-1 implementation to a ready-to-test state.
Tobias Markmann <tm@ayena.de>
parents: 2194
diff changeset
    20
local generate_uuid = require "util.uuid".generate;
2199
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2198
diff changeset
    21
local saslprep = require "util.encodings".stringprep.saslprep;
5301
6279caf921f1 util.sasl.{plain,scram,digest-md5}: nodeprep username before passing to callbacks, so callbacks don't have to.
Waqas Hussain <waqas20@gmail.com>
parents: 4368
diff changeset
    22
local nodeprep = require "util.encodings".stringprep.nodeprep;
2199
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2198
diff changeset
    23
local log = require "util.logger".init("sasl");
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    24
local t_concat = table.concat;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    25
local char = string.char;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    26
local byte = string.byte;
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    27
6789
3deeb38d79ab util.sasl.scram: Get rid of module call
Kim Alvefur <zash@zash.se>
parents: 5871
diff changeset
    28
local _ENV = nil;
8558
4f0f5b49bb03 vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    29
-- luacheck: std none
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    30
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    31
--=========================
3374
ce52f1d5cb74 util.sasl.scram: Reference actual RFC instead of the draft.
Tobias Markmann <tm@ayena.de>
parents: 3206
diff changeset
    32
--SASL SCRAM-SHA-1 according to RFC 5802
3097
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
    33
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
Supported Authentication Backends
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
    36
3122
579f17b9f948 util.sasl.*: Adjusting authentication provider names. All '-' replaced with '_'
Tobias Markmann <tm@ayena.de>
parents: 3118
diff changeset
    37
scram_{MECH}:
579f17b9f948 util.sasl.*: Adjusting authentication provider names. All '-' replaced with '_'
Tobias Markmann <tm@ayena.de>
parents: 3118
diff changeset
    38
	-- MECH being a standard hash name (like those at IANA's hash registry) with '-' replaced with '_'
3097
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
    39
	function(username, realm)
3205
2dcd826bbbc6 mod_auth_internal_hashed: Store StoredKey and ServerKey instead of salted hashed password.
Tobias Markmann <tm@ayena.de>
parents: 3196
diff changeset
    40
		return stored_key, server_key, iteration_count, salt, state;
3097
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
    41
	end
5836
fa8cfe830fef util.sasl.scram: Adding reference to RFC 5929 'Channel Bindings for TLS'.
Tobias Markmann <tm@ayena.de>
parents: 5835
diff changeset
    42
fa8cfe830fef util.sasl.scram: Adding reference to RFC 5929 'Channel Bindings for TLS'.
Tobias Markmann <tm@ayena.de>
parents: 5835
diff changeset
    43
Supported Channel Binding Backends
fa8cfe830fef util.sasl.scram: Adding reference to RFC 5929 'Channel Bindings for TLS'.
Tobias Markmann <tm@ayena.de>
parents: 5835
diff changeset
    44
fa8cfe830fef util.sasl.scram: Adding reference to RFC 5929 'Channel Bindings for TLS'.
Tobias Markmann <tm@ayena.de>
parents: 5835
diff changeset
    45
'tls-unique' according to RFC 5929
3097
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
    46
]]
9341ef1a3345 util.sasl.scram: Adding documentation on SCRAM authentication backend.
Tobias Markmann <tm@ayena.de>
parents: 3096
diff changeset
    47
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    48
local default_i = 4096
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    49
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    50
local xor_map = {
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    51
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    52
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    53
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    54
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    55
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    56
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    57
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    58
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    59
	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,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    60
	14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
    61
};
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    62
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    63
local result = {};
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    64
local function binaryXOR( a, b )
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    65
	for i=1, #a do
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    66
		local x, y = byte(a, i), byte(b, i);
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    67
		local lowx, lowy = x % 16, y % 16;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    68
		local hix, hiy = (x - lowx) / 16, (y - lowy) / 16;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    69
		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: 2290
diff changeset
    70
		local r = hir * 16 + lowr;
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    71
		result[i] = char(r)
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    72
	end
2314
c2e1bde4d84d Redo merge with Waqas' PBKDF2 optimizations.
Tobias Markmann <tm@ayena.de>
parents: 2290
diff changeset
    73
	return t_concat(result);
2194
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
5301
6279caf921f1 util.sasl.{plain,scram,digest-md5}: nodeprep username before passing to callbacks, so callbacks don't have to.
Waqas Hussain <waqas20@gmail.com>
parents: 4368
diff changeset
    76
local function validate_username(username, _nodeprep)
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    77
	-- check for forbidden char sequences
2198
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2197
diff changeset
    78
	for eq in username:gmatch("=(.?.?)") do
4204
edd7b0610c2c util.sasl.scram: Fix bug in validate_username function. (Thanks Florob)
Tobias Markmann <tm@ayena.de>
parents: 4113
diff changeset
    79
		if eq ~= "2C" and eq ~= "3D" then
3540
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 3405
diff changeset
    80
			return false
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 3405
diff changeset
    81
		end
2198
d18b4d22b8da Making interop with libpurple. (Thanks darkrain).
Tobias Markmann <tm@ayena.de>
parents: 2197
diff changeset
    82
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
    83
4204
edd7b0610c2c util.sasl.scram: Fix bug in validate_username function. (Thanks Florob)
Tobias Markmann <tm@ayena.de>
parents: 4113
diff changeset
    84
	-- replace =2C with , and =3D with =
edd7b0610c2c util.sasl.scram: Fix bug in validate_username function. (Thanks Florob)
Tobias Markmann <tm@ayena.de>
parents: 4113
diff changeset
    85
	username = username:gsub("=2C", ",");
2265
7fe644057dc2 util.sasl.scram: Making =2D and =3D substitution actually work.
Tobias Markmann <tm@ayena.de>
parents: 2255
diff changeset
    86
	username = username:gsub("=3D", "=");
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
    87
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    88
	-- apply SASLprep
2199
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2198
diff changeset
    89
	username = saslprep(username);
5301
6279caf921f1 util.sasl.{plain,scram,digest-md5}: nodeprep username before passing to callbacks, so callbacks don't have to.
Waqas Hussain <waqas20@gmail.com>
parents: 4368
diff changeset
    90
6279caf921f1 util.sasl.{plain,scram,digest-md5}: nodeprep username before passing to callbacks, so callbacks don't have to.
Waqas Hussain <waqas20@gmail.com>
parents: 4368
diff changeset
    91
	if username and _nodeprep ~= false then
6279caf921f1 util.sasl.{plain,scram,digest-md5}: nodeprep username before passing to callbacks, so callbacks don't have to.
Waqas Hussain <waqas20@gmail.com>
parents: 4368
diff changeset
    92
		username = (_nodeprep or nodeprep)(username);
6279caf921f1 util.sasl.{plain,scram,digest-md5}: nodeprep username before passing to callbacks, so callbacks don't have to.
Waqas Hussain <waqas20@gmail.com>
parents: 4368
diff changeset
    93
	end
6279caf921f1 util.sasl.{plain,scram,digest-md5}: nodeprep username before passing to callbacks, so callbacks don't have to.
Waqas Hussain <waqas20@gmail.com>
parents: 4368
diff changeset
    94
4368
916834f22d1b util.sasl.scram: Return proper error and don't touch datastores on empty username.
Waqas Hussain <waqas20@gmail.com>
parents: 4204
diff changeset
    95
	return username and #username>0 and username;
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    96
end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
    97
3155
c713fa2ba80c SASL: Minor cleanup.
Waqas Hussain <waqas20@gmail.com>
parents: 3154
diff changeset
    98
local function hashprep(hashname)
c713fa2ba80c SASL: Minor cleanup.
Waqas Hussain <waqas20@gmail.com>
parents: 3154
diff changeset
    99
	return hashname:lower():gsub("-", "_");
3122
579f17b9f948 util.sasl.*: Adjusting authentication provider names. All '-' replaced with '_'
Tobias Markmann <tm@ayena.de>
parents: 3118
diff changeset
   100
end
579f17b9f948 util.sasl.*: Adjusting authentication provider names. All '-' replaced with '_'
Tobias Markmann <tm@ayena.de>
parents: 3118
diff changeset
   101
6789
3deeb38d79ab util.sasl.scram: Get rid of module call
Kim Alvefur <zash@zash.se>
parents: 5871
diff changeset
   102
local function getAuthenticationDatabaseSHA1(password, salt, iteration_count)
3118
95ddd75ed3c5 util.sasl.scram: Fixing logic error in argument checking.
Tobias Markmann <tm@ayena.de>
parents: 3107
diff changeset
   103
	if type(password) ~= "string" or type(salt) ~= "string" or type(iteration_count) ~= "number" then
3104
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   104
		return false, "inappropriate argument types"
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   105
	end
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   106
	if iteration_count < 4096 then
3194
b308450740b0 util.sasl.scram: Fixed a log level.
Waqas Hussain <waqas20@gmail.com>
parents: 3123
diff changeset
   107
		log("warn", "Iteration count < 4096 which is the suggested minimum according to RFC 5802.")
3104
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   108
	end
5538
62089c9c142d util.hashes, util.sasl.scram: Implement SCRAM-SHA1's Hi in C
Florian Zeitz <florob@babelmonkeys.de>
parents: 5537
diff changeset
   109
	local salted_password = Hi(password, salt, iteration_count);
3205
2dcd826bbbc6 mod_auth_internal_hashed: Store StoredKey and ServerKey instead of salted hashed password.
Tobias Markmann <tm@ayena.de>
parents: 3196
diff changeset
   110
	local stored_key = sha1(hmac_sha1(salted_password, "Client Key"))
2dcd826bbbc6 mod_auth_internal_hashed: Store StoredKey and ServerKey instead of salted hashed password.
Tobias Markmann <tm@ayena.de>
parents: 3196
diff changeset
   111
	local server_key = hmac_sha1(salted_password, "Server Key");
2dcd826bbbc6 mod_auth_internal_hashed: Store StoredKey and ServerKey instead of salted hashed password.
Tobias Markmann <tm@ayena.de>
parents: 3196
diff changeset
   112
	return true, stored_key, server_key
3104
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   113
end
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   114
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
   115
local function scram_gen(hash_name, H_f, HMAC_f)
5870
61f748d363e1 util.sasl.scram: Cache profile name instead of concatenating when used
Kim Alvefur <zash@zash.se>
parents: 5869
diff changeset
   116
	local profile_name = "scram_" .. hashprep(hash_name);
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
   117
	local function scram_hash(self, message)
5833
b1fa865ee6b2 util.sasl.scram: Use self.profile.cb for detection whether channel binding is supported or not.
Tobias Markmann <tm@ayena.de>
parents: 5829
diff changeset
   118
		local support_channel_binding = false;
b1fa865ee6b2 util.sasl.scram: Use self.profile.cb for detection whether channel binding is supported or not.
Tobias Markmann <tm@ayena.de>
parents: 5829
diff changeset
   119
		if self.profile.cb then support_channel_binding = true; end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   120
3106
f4341cac3ae1 util.sasl.scram: Fixing issue #177.
Tobias Markmann <tm@ayena.de>
parents: 3104
diff changeset
   121
		if type(message) ~= "string" or #message == 0 then return "failure", "malformed-request" end
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   122
		local state = self.state;
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   123
		if not state then
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
			-- 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
   125
			local client_first_message = message;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   126
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
   127
			-- TODO: fail if authzid is provided, since we don't support them yet
5871
e80916ce8d32 util.sasl.scram: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 5870
diff changeset
   128
			local gs2_header, gs2_cbind_flag, gs2_cbind_name, authzid, client_first_message_bare, username, clientnonce
5869
35780ef2d689 util.sasl.scram: Rewrite patterns and capture client-first-message-bare, client-final-message-without-proof
Kim Alvefur <zash@zash.se>
parents: 5868
diff changeset
   129
				= s_match(client_first_message, "^(([pny])=?([^,]*),([^,]*),)(m?=?[^,]*,?n=([^,]*),r=([^,]*),?.*)$");
3100
6731dff05c99 util.sasl.scram: Parsing client-first-message in a more strict way. (thanks Marc Santamaria)
Tobias Markmann <tm@ayena.de>
parents: 3099
diff changeset
   130
5844
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   131
			if not gs2_cbind_flag then
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   132
				return "failure", "malformed-request";
5839
a65b56348034 util.sasl.scram: Checking the GS2 header for valid start flag.
Tobias Markmann <tm@ayena.de>
parents: 5837
diff changeset
   133
			end
a65b56348034 util.sasl.scram: Checking the GS2 header for valid start flag.
Tobias Markmann <tm@ayena.de>
parents: 5837
diff changeset
   134
5844
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   135
			if support_channel_binding and gs2_cbind_flag == "y" then
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   136
				-- "y" -> client does support channel binding
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   137
				--        but thinks the server does not.
5828
24de22c01f8d Adding some code for channel binding advertising.
Tobias Markmann <tm@ayena.de>
parents: 3981
diff changeset
   138
					return "failure", "malformed-request";
24de22c01f8d Adding some code for channel binding advertising.
Tobias Markmann <tm@ayena.de>
parents: 3981
diff changeset
   139
				end
5844
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   140
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   141
			if gs2_cbind_flag == "n" then
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   142
				-- "n" -> client doesn't support channel binding.
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   143
				support_channel_binding = false;
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   144
			end
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   145
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   146
			if support_channel_binding and gs2_cbind_flag == "p" then
5829
40c16475194e Check whether we support the proposed channel binding type.
Tobias Markmann <tm@ayena.de>
parents: 5828
diff changeset
   147
				-- check whether we support the proposed channel binding type
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   148
				if not self.profile.cb[gs2_cbind_name] then
5829
40c16475194e Check whether we support the proposed channel binding type.
Tobias Markmann <tm@ayena.de>
parents: 5828
diff changeset
   149
					return "failure", "malformed-request", "Proposed channel binding type isn't supported.";
40c16475194e Check whether we support the proposed channel binding type.
Tobias Markmann <tm@ayena.de>
parents: 5828
diff changeset
   150
				end
5828
24de22c01f8d Adding some code for channel binding advertising.
Tobias Markmann <tm@ayena.de>
parents: 3981
diff changeset
   151
			else
5844
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   152
				-- no channel binding,
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   153
				gs2_cbind_name = nil;
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
   154
			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
   155
5871
e80916ce8d32 util.sasl.scram: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 5870
diff changeset
   156
			username = validate_username(username, self.profile.nodeprep);
e80916ce8d32 util.sasl.scram: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 5870
diff changeset
   157
			if not username then
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
   158
				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
   159
				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
   160
			end
8098
57192cf193c7 util.sasl.plain,scram: Record username in sasl state earlier
Kim Alvefur <zash@zash.se>
parents: 7221
diff changeset
   161
			self.username = username;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   162
8731
41c959c5c84b Fix spelling throughout the codebase [codespell]
Kim Alvefur <zash@zash.se>
parents: 8558
diff changeset
   163
			-- retrieve credentials
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   164
			local stored_key, server_key, salt, iteration_count;
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
   165
			if self.profile.plain then
7219
65e36b81d56a util.sasl.scram: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6789
diff changeset
   166
				local password, status = self.profile.plain(self, username, self.realm)
65e36b81d56a util.sasl.scram: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6789
diff changeset
   167
				if status == nil then return "failure", "not-authorized"
65e36b81d56a util.sasl.scram: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6789
diff changeset
   168
				elseif status == false then return "failure", "account-disabled" end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   169
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
   170
				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
   171
				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
   172
					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
   173
					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
   174
				end
3104
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   175
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   176
				salt = generate_uuid();
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   177
				iteration_count = default_i;
3104
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   178
7220
0a43b7ffa3af util.sasl.scram: Remove unused initial value [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7219
diff changeset
   179
				local succ;
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   180
				succ, stored_key, server_key = getAuthenticationDatabaseSHA1(password, salt, iteration_count);
3104
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   181
				if not succ then
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   182
					log("error", "Generating authentication database failed. Reason: %s", stored_key);
3104
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   183
					return "failure", "temporary-auth-failure";
32150b4a8603 util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
Tobias Markmann <tm@ayena.de>
parents: 3103
diff changeset
   184
				end
5870
61f748d363e1 util.sasl.scram: Cache profile name instead of concatenating when used
Kim Alvefur <zash@zash.se>
parents: 5869
diff changeset
   185
			elseif self.profile[profile_name] then
7219
65e36b81d56a util.sasl.scram: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6789
diff changeset
   186
				local status;
65e36b81d56a util.sasl.scram: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6789
diff changeset
   187
				stored_key, server_key, iteration_count, salt, status = self.profile[profile_name](self, username, self.realm);
7221
6226307f6ac4 util.sasl.scram: Rename variable in places missed in 65e36b81d56a (thanks mt)
Kim Alvefur <zash@zash.se>
parents: 7220
diff changeset
   188
				if status == nil then return "failure", "not-authorized"
6226307f6ac4 util.sasl.scram: Rename variable in places missed in 65e36b81d56a (thanks mt)
Kim Alvefur <zash@zash.se>
parents: 7220
diff changeset
   189
				elseif status == false then return "failure", "account-disabled" 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
   190
			end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   191
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   192
			local nonce = clientnonce .. generate_uuid();
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   193
			local server_first_message = "r="..nonce..",s="..base64.encode(salt)..",i="..iteration_count;
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   194
			self.state = {
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   195
				gs2_header = gs2_header;
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   196
				gs2_cbind_name = gs2_cbind_name;
5871
e80916ce8d32 util.sasl.scram: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 5870
diff changeset
   197
				username = username;
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   198
				nonce = nonce;
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   199
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   200
				server_key = server_key;
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   201
				stored_key = stored_key;
5869
35780ef2d689 util.sasl.scram: Rewrite patterns and capture client-first-message-bare, client-final-message-without-proof
Kim Alvefur <zash@zash.se>
parents: 5868
diff changeset
   202
				client_first_message_bare = client_first_message_bare;
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   203
				server_first_message = server_first_message;
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   204
			}
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
   205
			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
   206
		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
   207
			-- 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
   208
			local client_final_message = message;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   209
5869
35780ef2d689 util.sasl.scram: Rewrite patterns and capture client-first-message-bare, client-final-message-without-proof
Kim Alvefur <zash@zash.se>
parents: 5868
diff changeset
   210
			local client_final_message_without_proof, channelbinding, nonce, proof
35780ef2d689 util.sasl.scram: Rewrite patterns and capture client-first-message-bare, client-final-message-without-proof
Kim Alvefur <zash@zash.se>
parents: 5868
diff changeset
   211
				= s_match(client_final_message, "(c=([^,]*),r=([^,]*),?.-),p=(.*)$");
5835
a5f4de8c0b40 util.sasl.scram: Validate channel binding data of client final message.
Tobias Markmann <tm@ayena.de>
parents: 5833
diff changeset
   212
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   213
			if not proof or not nonce or not channelbinding then
5840
4b484e8feafc sasl.util.scarm: Rearrage some code so it makes more sense.
Tobias Markmann <tm@ayena.de>
parents: 5839
diff changeset
   214
				return "failure", "malformed-request", "Missing an attribute(p, r or c) in SASL message.";
4b484e8feafc sasl.util.scarm: Rearrage some code so it makes more sense.
Tobias Markmann <tm@ayena.de>
parents: 5839
diff changeset
   215
			end
4b484e8feafc sasl.util.scarm: Rearrage some code so it makes more sense.
Tobias Markmann <tm@ayena.de>
parents: 5839
diff changeset
   216
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   217
			local client_gs2_header = base64.decode(channelbinding)
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   218
			local our_client_gs2_header = state["gs2_header"]
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   219
			if state.gs2_cbind_name then
5840
4b484e8feafc sasl.util.scarm: Rearrage some code so it makes more sense.
Tobias Markmann <tm@ayena.de>
parents: 5839
diff changeset
   220
				-- we support channelbinding, so check if the value is valid
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   221
				our_client_gs2_header = our_client_gs2_header .. self.profile.cb[state.gs2_cbind_name](self);
5867
72d49d1e2d11 util.sasl.scram: Compare gs2-header to cbind-input (Thanks Tobias)
Kim Alvefur <zash@zash.se>
parents: 5856
diff changeset
   222
			end
72d49d1e2d11 util.sasl.scram: Compare gs2-header to cbind-input (Thanks Tobias)
Kim Alvefur <zash@zash.se>
parents: 5856
diff changeset
   223
			if client_gs2_header ~= our_client_gs2_header then
72d49d1e2d11 util.sasl.scram: Compare gs2-header to cbind-input (Thanks Tobias)
Kim Alvefur <zash@zash.se>
parents: 5856
diff changeset
   224
				return "failure", "malformed-request", "Invalid channel binding value.";
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
   225
			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
   226
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   227
			if nonce ~= state.nonce then
3101
9e4439378cf8 util.sasl.scram: Fix in nonce check of client-final-message.
Tobias Markmann <tm@ayena.de>
parents: 3100
diff changeset
   228
				return "failure", "malformed-request", "Wrong nonce in client-final-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
   229
			end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   230
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   231
			local ServerKey = state.server_key;
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   232
			local StoredKey = state.stored_key;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5538
diff changeset
   233
5869
35780ef2d689 util.sasl.scram: Rewrite patterns and capture client-first-message-bare, client-final-message-without-proof
Kim Alvefur <zash@zash.se>
parents: 5868
diff changeset
   234
			local AuthMessage = state.client_first_message_bare .. "," .. state.server_first_message .. "," .. client_final_message_without_proof
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
   235
			local ClientSignature = HMAC_f(StoredKey, AuthMessage)
5868
bc37c6758f3a util.sasl.scram: Create the state table as late as possible, keep state in locals for faster access
Kim Alvefur <zash@zash.se>
parents: 5867
diff changeset
   236
			local ClientKey = binaryXOR(ClientSignature, base64.decode(proof))
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
   237
			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
   238
3206
ff1d3f751da1 util.sasl.scram: Authenticate clients by calculated StoredKey instead of ClientProof.
Tobias Markmann <tm@ayena.de>
parents: 3205
diff changeset
   239
			if StoredKey == H_f(ClientKey) then
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
   240
				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
   241
				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
   242
			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
   243
				return "failure", "not-authorized", "The response provided by the client doesn't match the one we calculated.";
2199
08a6b91bfe7b SASLprep usernames and passwords.
Tobias Markmann <tm@ayena.de>
parents: 2198
diff changeset
   244
			end
2196
614c839c30c5 Completed SCRAM-SHA-1 implementation to a ready-to-test state.
Tobias Markmann <tm@ayena.de>
parents: 2194
diff changeset
   245
		end
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
   246
	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
   247
	return scram_hash;
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
   248
end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
   249
6789
3deeb38d79ab util.sasl.scram: Get rid of module call
Kim Alvefur <zash@zash.se>
parents: 5871
diff changeset
   250
local 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
   251
	local function registerSCRAMMechanism(hash_name, hash, hmac_hash)
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
   252
		registerMechanism("SCRAM-"..hash_name,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
   253
			{"plain", "scram_"..(hashprep(hash_name))},
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
   254
			scram_gen(hash_name:lower(), hash, hmac_hash));
5844
4f545674b0bc util.sasl.scram: Simplify validation of client-first-message
Kim Alvefur <zash@zash.se>
parents: 5843
diff changeset
   255
5828
24de22c01f8d Adding some code for channel binding advertising.
Tobias Markmann <tm@ayena.de>
parents: 3981
diff changeset
   256
		-- register channel binding equivalent
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
   257
		registerMechanism("SCRAM-"..hash_name.."-PLUS",
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
   258
			{"plain", "scram_"..(hashprep(hash_name))},
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8098
diff changeset
   259
			scram_gen(hash_name:lower(), hash, hmac_hash), {"tls-unique"});
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
   260
	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
   261
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
   262
	registerSCRAMMechanism("SHA-1", sha1, hmac_sha1);
2194
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
   263
end
41d42d253a1d Initial commit of SCRAM SASL mechanism.
Tobias Markmann <tm@ayena.de>
parents:
diff changeset
   264
6789
3deeb38d79ab util.sasl.scram: Get rid of module call
Kim Alvefur <zash@zash.se>
parents: 5871
diff changeset
   265
return {
3deeb38d79ab util.sasl.scram: Get rid of module call
Kim Alvefur <zash@zash.se>
parents: 5871
diff changeset
   266
	getAuthenticationDatabaseSHA1 = getAuthenticationDatabaseSHA1;
3deeb38d79ab util.sasl.scram: Get rid of module call
Kim Alvefur <zash@zash.se>
parents: 5871
diff changeset
   267
	init = init;
3deeb38d79ab util.sasl.scram: Get rid of module call
Kim Alvefur <zash@zash.se>
parents: 5871
diff changeset
   268
}