@@ -19,6 +19,8 @@ void CLuaCryptDefs::LoadFunctions ( void )
1919 CLuaCFunctions::AddFunction ( " teaDecode" , TeaDecode );
2020 CLuaCFunctions::AddFunction ( " base64Encode" , Base64encode );
2121 CLuaCFunctions::AddFunction ( " base64Decode" , Base64decode );
22+ CLuaCFunctions::AddFunction (" passwordHash" , PasswordHash);
23+ CLuaCFunctions::AddFunction (" passwordVerify" , PasswordVerify);
2224}
2325
2426int CLuaCryptDefs::Md5 ( lua_State* luaVM )
@@ -173,3 +175,78 @@ int CLuaCryptDefs::Base64decode ( lua_State* luaVM )
173175 lua_pushboolean ( luaVM, false );
174176 return 1 ;
175177}
178+
179+ int CLuaCryptDefs::PasswordHash (lua_State* luaVM)
180+ {
181+ // string password_hash(string password, string algorithm, table options = {})
182+ SString password;
183+ PasswordHashFunction algorithm;
184+ std::unordered_map<SString, SString> options;
185+
186+ CScriptArgReader argStream (luaVM);
187+ argStream.ReadString (password);
188+ argStream.ReadEnumString (algorithm);
189+ argStream.ReadStringMap (options, true );
190+
191+ if (!argStream.HasErrors ())
192+ {
193+ if (algorithm == PasswordHashFunction::Bcrypt)
194+ {
195+ // Set default value to 10
196+ if (options[" cost" ].empty ())
197+ options[" cost" ] = " 10" ;
198+
199+ std::stringstream ss (options[" cost" ]);
200+ std::size_t cost;
201+ ss >> cost;
202+
203+ if (!ss.fail ())
204+ {
205+ SString hash = SharedUtil::BcryptHash (password, options[" salt" ], cost);
206+ if (!hash.empty ())
207+ {
208+ lua_pushstring (luaVM, hash);
209+ return 1 ;
210+ }
211+ else
212+ m_pScriptDebugging->LogCustom (luaVM, " Invalid value for field 'salt'" );
213+ }
214+ else
215+ m_pScriptDebugging->LogWarning (luaVM, " Invalid value for field 'cost'" );
216+ }
217+ }
218+ else
219+ m_pScriptDebugging->LogCustom (luaVM, argStream.GetFullErrorMessage ());
220+
221+ lua_pushboolean (luaVM, false );
222+ return 1 ;
223+ }
224+
225+ int CLuaCryptDefs::PasswordVerify (lua_State* luaVM)
226+ {
227+ // bool passwordVerify(string password, string hash)
228+ SString password;
229+ SString hash;
230+
231+ CScriptArgReader argStream (luaVM);
232+ argStream.ReadString (password);
233+ argStream.ReadString (hash);
234+
235+ if (!argStream.HasErrors ())
236+ {
237+ if (hash.BeginsWith (" $2y$" ))
238+ {
239+ lua_pushboolean (luaVM, SharedUtil::BcryptVerify (password, hash));
240+ return 1 ;
241+ }
242+ else
243+ {
244+ m_pScriptDebugging->LogWarning (luaVM, " Passed unknown hash" );
245+ }
246+ }
247+ else
248+ m_pScriptDebugging->LogCustom (luaVM, argStream.GetFullErrorMessage ());
249+
250+ lua_pushboolean (luaVM, false );
251+ return 1 ;
252+ }
0 commit comments