97 lines
2.8 KiB
PHP
97 lines
2.8 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace alveolata\auth;
|
||
|
|
||
|
require_once(DIR_ALVEOLATA . '/auth/implementation-srp/core.php');
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @param struct_srp_subject<type_number> $subject
|
||
|
* @param function<tuple<>,string> $generate_salt
|
||
|
* @param function<tuple<string,string,string>,void> $handle
|
||
|
*/
|
||
|
function srp_client_register/*<type_number>*/(
|
||
|
struct_srp_subject/*<type_number>*/ $subject,
|
||
|
\Closure $generate_salt,
|
||
|
\Closure $handle
|
||
|
) : \Closure
|
||
|
{
|
||
|
return (
|
||
|
function ($username, $password) use (&$subject, &$generate_salt, &$handle) {
|
||
|
$salt = $generate_salt();
|
||
|
$compute_verifier_result = srp_compute_verifier(
|
||
|
$subject,
|
||
|
$salt,
|
||
|
$password
|
||
|
);
|
||
|
$verifier = $compute_verifier_result['verifier'];
|
||
|
$response1 = $handle(
|
||
|
$username,
|
||
|
$salt,
|
||
|
($subject->toolset->encode)($verifier)
|
||
|
);
|
||
|
return true;
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @param function<tuple<string,string>,record<passed:boolean,salt:string,b_value:string>> $handle1
|
||
|
* @param function<tuple<string>,record<passed:boolean,m2_server:string>> $handle2
|
||
|
* @return function<tuple<string,string>,boolean>
|
||
|
*/
|
||
|
function srp_client_login/*<type_number>*/(
|
||
|
struct_srp_subject/*<type_number>*/ $subject,
|
||
|
\Closure $handle1,
|
||
|
\Closure $handle2
|
||
|
) : \Closure
|
||
|
{
|
||
|
return (
|
||
|
function (string $username, string $password) use (&$subject, &$handle1, &$handle2) {
|
||
|
$computeAResult = srp_compute_a($subject);
|
||
|
$a_exponent = $computeAResult['a_exponent'];
|
||
|
$a_value = $computeAResult['a_value'];
|
||
|
$k = $computeAResult['k'];
|
||
|
$response1 = $handle1($username, ($subject->toolset->encode)($a_value));
|
||
|
$salt = $response1['salt'];
|
||
|
$b_value = ($subject->toolset->decode)($response1['b_value']);
|
||
|
if (! $response1['passed']) {
|
||
|
return false;
|
||
|
}
|
||
|
else {
|
||
|
$verifiedB = srp_verify_b($subject, $b_value);
|
||
|
$verifiedHAB = srp_verify_hab($subject, $a_exponent, $b_value);
|
||
|
if (! ($verifiedB && $verifiedHAB)) {
|
||
|
throw (new \Exception('connection security fault'));
|
||
|
}
|
||
|
else {
|
||
|
$computeVerifierResult = srp_compute_verifier($subject, $salt, $password);
|
||
|
$x = $computeVerifierResult['x'];
|
||
|
$computeClientKResult = srp_compute_k_client($subject, $a_exponent, $a_value, $b_value, $x, $k);
|
||
|
$k_client = $computeClientKResult['k_client'];
|
||
|
$computeClientM1Result = srp_compute_m1_client($subject, $salt, $a_value, $b_value, $username, $k_client);
|
||
|
$m1_client = $computeClientM1Result['m1_client'];
|
||
|
$response2 = $handle2($m1_client);
|
||
|
$m2_server = $response2['m2_server'];
|
||
|
if (! $response2['passed']) {
|
||
|
return false;
|
||
|
}
|
||
|
else {
|
||
|
$computeClientM2Result = srp_compute_m2_client($subject, $a_value, $m1_client, $k_client);
|
||
|
$m2_client = $computeClientM2Result['m2_client'];
|
||
|
if (! ($m2_server === $m2_client)) {
|
||
|
return false;
|
||
|
}
|
||
|
else {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
?>
|