rosavox/lib/alveolata/auth/implementation-srp/functions-client.php

97 lines
2.8 KiB
PHP
Raw Normal View History

2025-05-23 07:33:29 +00:00
<?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;
}
}
}
}
}
);
}
?>