This commit is contained in:
Roland Gruber 2019-11-28 21:19:44 +01:00
parent 58e15da1a8
commit 4d5d93c62b
5 changed files with 84 additions and 15 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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('<input type="hidden" name="sig_response" value="' + response + '"/>');
form.submit();
}, function (error) {
console.log(error);
});

View File

@ -132,7 +132,7 @@ printJsIncludes('..');
<br><br>
<form enctype="multipart/form-data" action="login2Factor.php" method="post" autocomplete="off">
<form id="2faform" enctype="multipart/form-data" action="login2Factor.php" method="post" autocomplete="off">
<?php
echo $config->getTwoFactorAuthenticationCaption();

View File

@ -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',