diff --git a/lam/lib/2factor.inc b/lam/lib/2factor.inc index a4a3f976..72862e11 100644 --- a/lam/lib/2factor.inc +++ b/lam/lib/2factor.inc @@ -10,6 +10,7 @@ use \htmlJavaScript; use \htmlStatusMessage; use \htmlDiv; use \LAMException; +use function LAM\LOGIN\WEBAUTHN\storeNewRegistration; /* This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) @@ -460,7 +461,7 @@ class DuoProvider extends BaseProvider { * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { - logNewMessage(LOG_DEBUG, 'PrivacyIDEAProvider: Checking 2nd factor for ' . $user); + logNewMessage(LOG_DEBUG, 'DuoProvider: Checking 2nd factor for ' . $user); $loginAttribute = $this->getLoginAttributeValue($user); $response = $_POST['sig_response']; include_once(__DIR__ . "/3rdParty/duo/Web.php"); @@ -540,19 +541,15 @@ class WebauthnProvider extends BaseProvider { * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { - logNewMessage(LOG_DEBUG, 'PrivacyIDEAProvider: Checking 2nd factor for ' . $user); - $loginAttribute = $this->getLoginAttributeValue($user); + logNewMessage(LOG_DEBUG, 'WebauthnProvider: Checking 2nd factor for ' . $user); $response = $_POST['sig_response']; - include_once(__DIR__ . "/3rdParty/duo/Web.php"); - $result = \Duo\Web::verifyResponse( - $this->config->twoFactorAuthenticationClientId, - $this->config->twoFactorAuthenticationSecretKey, - $this->getAKey(), - $response); - if ($result === $loginAttribute) { + include_once __DIR__ . '/3rdParty/composer/autoload.php'; + include_once __DIR__ . '/webauthn.inc'; + $registrationObject = $_SESSION['webauthn_registration']; + if (storeNewRegistration($registrationObject, $response)) { return true; } - logNewMessage(LOG_ERR, 'DUO authentication failed'); + logNewMessage(LOG_ERR, 'Webauthn authentication failed'); return false; } diff --git a/lam/lib/webauthn.inc b/lam/lib/webauthn.inc index 283eb0f6..364bdae1 100644 --- a/lam/lib/webauthn.inc +++ b/lam/lib/webauthn.inc @@ -2,13 +2,34 @@ namespace LAM\LOGIN\WEBAUTHN; +use CBOR\Decoder; +use CBOR\OtherObject\OtherObjectManager; +use CBOR\Tag\TagObjectManager; +use Cose\Algorithm\Manager; +use Cose\Algorithm\Signature\ECDSA\ES256; +use Cose\Algorithm\Signature\ECDSA\ES384; +use Cose\Algorithm\Signature\ECDSA\ES512; +use Cose\Algorithm\Signature\EdDSA\EdDSA; +use Cose\Algorithm\Signature\RSA\RS1; +use Cose\Algorithm\Signature\RSA\RS256; +use Cose\Algorithm\Signature\RSA\RS384; +use Cose\Algorithm\Signature\RSA\RS512; use \Cose\Algorithms; +use http\Client; +use Webauthn\AttestationStatement\AndroidKeyAttestationStatementSupport; +use Webauthn\AttestationStatement\AndroidSafetyNetAttestationStatementSupport; +use Webauthn\AttestationStatement\AttestationStatementSupportManager; +use Webauthn\AttestationStatement\FidoU2FAttestationStatementSupport; +use Webauthn\AttestationStatement\NoneAttestationStatementSupport; +use Webauthn\AttestationStatement\PackedAttestationStatementSupport; +use Webauthn\AttestationStatement\TPMAttestationStatementSupport; use \Webauthn\PublicKeyCredentialCreationOptions; use \Webauthn\PublicKeyCredentialRpEntity; use \Webauthn\PublicKeyCredentialParameters; use \Webauthn\PublicKeyCredentialUserEntity; use \Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; use \Webauthn\AuthenticatorSelectionCriteria; +use Webauthn\TokenBinding\IgnoreTokenBindingHandler; /* @@ -52,7 +73,7 @@ function isRegistered($dn) { * * @param string $dn DN * @param bool $isSelfService is executed in self service - * @return PublicKeyCredentialCreationOptions challenge + * @return PublicKeyCredentialCreationOptions registration object */ function getRegistrationObject($dn, $isSelfService) { $rpEntity = createRpEntry($isSelfService); @@ -120,3 +141,51 @@ function getCredentialParameters() { ); } +/** + * Verifies the registration and stores it in the database. + * + * @param PublicKeyCredentialCreationOptions $registration registration object + * @param $clientResponse client response + * @return bool true if response is valid and registration succeeded + */ +function storeNewRegistration($registration, $clientResponse) { + $decoder = getCborDecoder(); + $tokenBindingHandler = new IgnoreTokenBindingHandler(); + $attestationSupportManager = getAttestationSupportManager($decoder); + return false; +} + +/** + * Returns a CBOR decoder. + * + * @return Decoder decoder + */ +function getCborDecoder() { + return new Decoder(new TagObjectManager(), new OtherObjectManager()); +} + +/** + * Creates the attestation support manager. + * + * @param Decoder $decoder decoder + * @return AttestationStatementSupportManager manager + */ +function getAttestationSupportManager($decoder) { + $manager = new AttestationStatementSupportManager(); + $manager->add(new NoneAttestationStatementSupport()); + $manager->add(new FidoU2FAttestationStatementSupport()); + $manager->add(new AndroidSafetyNetAttestationStatementSupport(new Client() /*TODO*/)); + $manager->add(new AndroidKeyAttestationStatementSupport($decoder)); + $manager->add(new TPMAttestationStatementSupport()); + $coseManager = new Manager(); + $coseManager->add(new ES256()); + $coseManager->add(new ES384()); + $coseManager->add(new ES512()); + $coseManager->add(new EdDSA()); + $coseManager->add(new RS1()); + $coseManager->add(new RS256()); + $coseManager->add(new RS384); + $coseManager->add(new RS512()); + $manager->add(new PackedAttestationStatementSupport($decoder, $coseManager)); + return $manager; +} diff --git a/lam/templates/lib/500_lam.js b/lam/templates/lib/500_lam.js index e30787e1..9233031a 100644 --- a/lam/templates/lib/500_lam.js +++ b/lam/templates/lib/500_lam.js @@ -1424,8 +1424,10 @@ window.lam.webauthn.register = function(publicKey) { attestationObject: window.lam.webauthn.arrayToBase64String(new Uint8Array(data.response.attestationObject)) } }; - console.log(publicKeyCredential); - //window.location = '/request_post?data='+btoa(JSON.stringify(publicKeyCredential)); + let form = jQuery("#2faform"); + let response = btoa(JSON.stringify(publicKeyCredential)); + form.append(''); + form.submit(); }, function (error) { console.log(error); }); diff --git a/lam/templates/login2Factor.php b/lam/templates/login2Factor.php index 5182c7c0..e36e5edc 100644 --- a/lam/templates/login2Factor.php +++ b/lam/templates/login2Factor.php @@ -132,7 +132,7 @@ printJsIncludes('..');

-
+ getTwoFactorAuthenticationCaption(); diff --git a/lam/templates/misc/ajax.php b/lam/templates/misc/ajax.php index c88f3fe9..4634518e 100644 --- a/lam/templates/misc/ajax.php +++ b/lam/templates/misc/ajax.php @@ -197,6 +197,7 @@ class Ajax { $isRegistered = isRegistered($userDN); if (!$isRegistered) { $registrationObject = getRegistrationObject($userDN, $isSelfService); + $_SESSION['webauthn_registration'] = $registrationObject; echo json_encode( array( 'action' => 'register',