Skip to content

Commit

Permalink
Anon ca (#181)
Browse files Browse the repository at this point in the history
* AnonCA as per approved Webauthn L2
* otherUI
* Use Presence check restored. Final behavior to be clarified
  • Loading branch information
Spomky authored Apr 16, 2021
1 parent de5cd24 commit 572e239
Show file tree
Hide file tree
Showing 11 changed files with 38 additions and 42 deletions.
35 changes: 0 additions & 35 deletions .github/workflows/security.yml

This file was deleted.

3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ Webauthn Framework

![Build Status](https://github.com/web-auth/webauthn-framework/workflows/Coding%20Standards/badge.svg)
![Build Status](https://github.com/web-auth/webauthn-framework/workflows/Static%20Analyze/badge.svg)
![Build Status](https://github.com/web-auth/webauthn-framework/workflows/Security/badge.svg)

![Build Status](https://github.com/web-auth/webauthn-framework/workflows/Backwards%20compatibility%20verification/badge.svg)

Expand All @@ -20,7 +19,7 @@ Webauthn Framework

Webauthn defines an API enabling the creation and use of strong, attested, scoped, public key-based credentials by web applications, for the purpose of strongly authenticating users.

This framework contains PHP libraries and Symfony bundle to allow developpers to integrate that authentication mechanism into their web applications.
This framework contains PHP libraries and Symfony bundle to allow developers to integrate that authentication mechanism into their web applications.

# Documentation

Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ parameters:
- '#Call to deprecated function Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ref\(\)(.*)#'
- '#Parameter (.*) of class FG\\ASN1\\Universal\\Integer constructor expects int, string given\.#'
- '#Instanceof between Symfony\\Component\\HttpFoundation\\Response and Symfony\\Component\\HttpFoundation\\Response will always evaluate to true\.#'
- '#Parameter (.*) of class Jose\\Component\\Core\\AlgorithmManager constructor expects array\<Jose\\Component\\Core\\Algorithm\>\, array\<int\, object\> given\.#'
checkMissingIterableValueType: false
checkGenericClassInNonGenericObjectType: false
treatPhpDocTypesAsCertain: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,9 @@ private function initJwsVerifier(): void
Algorithm\ES256::class, Algorithm\ES384::class, Algorithm\ES512::class,
Algorithm\EdDSA::class,
];
/* @var AlgorithmInterface[] $algorithms */
$algorithms = [];
foreach ($algorithmClasses as $key => $algorithm) {
foreach ($algorithmClasses as $algorithm) {
if (class_exists($algorithm)) {
/* @var AlgorithmInterface $algorithm */
$algorithms[] = new $algorithm();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function load(array $attestation): AttestationStatement
Assertion::allString($certificates, 'The attestation statement value "x5c" must be a list with at least one certificate.');
$certificates = CertificateToolbox::convertAllDERToPEM($certificates);

return AttestationStatement::createBasic($attestation['fmt'], $attestation['attStmt'], new CertificateTrustPath($certificates));
return AttestationStatement::createAnonymizationCA($attestation['fmt'], $attestation['attStmt'], new CertificateTrustPath($certificates));
}

public function isValid(string $clientDataJSONHash, AttestationStatement $attestationStatement, AuthenticatorData $authenticatorData): bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class AttestationStatement implements JsonSerializable
public const TYPE_SELF = 'self';
public const TYPE_ATTCA = 'attca';
public const TYPE_ECDAA = 'ecdaa';
public const TYPE_ANONCA = 'anonca';

/**
* @var string
Expand Down Expand Up @@ -99,6 +100,11 @@ public static function createEcdaa(string $fmt, array $attStmt, TrustPath $trust
return new self($fmt, $attStmt, self::TYPE_ECDAA, $trustPath);
}

public static function createAnonymizationCA(string $fmt, array $attStmt, TrustPath $trustPath): self
{
return new self($fmt, $attStmt, self::TYPE_ANONCA, $trustPath);
}

public function getFmt(): string
{
return $this->fmt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth
Assertion::true(hash_equals($rpIdHash, $authenticatorAssertionResponse->getAuthenticatorData()->getRpIdHash()), 'rpId hash mismatch.');

/* @see 7.2.12 */
//Nothing to do. The verification of the bit is done during the authenticator data loading
Assertion::true($authenticatorAssertionResponse->getAuthenticatorData()->isUserPresent(), 'User was not present');
/* @see 7.2.13 */
if (AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED === $publicKeyCredentialRequestOptions->getUserVerification()) {
Assertion::true($authenticatorAssertionResponse->getAuthenticatorData()->isUserVerified(), 'User authentication required.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function check(AuthenticatorAttestationResponse $authenticatorAttestation
Assertion::true(hash_equals($rpIdHash, $attestationObject->getAuthData()->getRpIdHash()), 'rpId hash mismatch.');

/* @see 7.1.10 */
//Nothing to do. The verification of the bit is done during the authenticator data loading
Assertion::true($attestationObject->getAuthData()->isUserPresent(), 'User was not present');
/* @see 7.1.11 */
if (AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED === $publicKeyCredentialCreationOptions->getAuthenticatorSelection()->getUserVerification()) {
Assertion::true($attestationObject->getAuthData()->isUserVerified(), 'User authentication required.');
Expand Down
20 changes: 19 additions & 1 deletion src/webauthn/src/PublicKeyCredentialSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,15 @@ class PublicKeyCredentialSource implements JsonSerializable
*/
protected $counter;

/**
* @var array|null
*/
protected $otherUI;

/**
* @param string[] $transports
*/
public function __construct(string $publicKeyCredentialId, string $type, array $transports, string $attestationType, TrustPath $trustPath, UuidInterface $aaguid, string $credentialPublicKey, string $userHandle, int $counter)
public function __construct(string $publicKeyCredentialId, string $type, array $transports, string $attestationType, TrustPath $trustPath, UuidInterface $aaguid, string $credentialPublicKey, string $userHandle, int $counter, ?array $otherUI = null)
{
$this->publicKeyCredentialId = $publicKeyCredentialId;
$this->type = $type;
Expand All @@ -89,6 +94,7 @@ public function __construct(string $publicKeyCredentialId, string $type, array $
$this->counter = $counter;
$this->attestationType = $attestationType;
$this->trustPath = $trustPath;
$this->otherUI = $otherUI;
}

public function getPublicKeyCredentialId(): string
Expand Down Expand Up @@ -162,6 +168,18 @@ public function setCounter(int $counter): void
$this->counter = $counter;
}

public function getOtherUI(): ?array
{
return $this->otherUI;
}

public function setOtherUI(?array $otherUI): self
{
$this->otherUI = $otherUI;

return $this;
}

/**
* @param mixed[] $data
*/
Expand Down
1 change: 1 addition & 0 deletions src/webauthn/src/PublicKeyCredentialUserEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class PublicKeyCredentialUserEntity extends PublicKeyCredentialEntity
public function __construct(string $name, string $id, string $displayName, ?string $icon = null)
{
parent::__construct($name, $icon);
Assertion::maxLength($id, 64, 'User ID max length is 64 bytes', 'id', '8bit');
$this->id = $id;
$this->displayName = $displayName;
}
Expand Down
5 changes: 5 additions & 0 deletions tests/library/Functional/AppleAttestationStatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Base64Url\Base64Url;
use Cose\Algorithms;
use Symfony\Bridge\PhpUnit\ClockMock;
use Webauthn\AttestationStatement\AttestationStatement;
use Webauthn\AttestedCredentialData;
use Webauthn\AuthenticatorAttestationResponse;
use Webauthn\AuthenticatorData;
Expand Down Expand Up @@ -86,6 +87,10 @@ public function anAppleAttestationCanBeVerified(): void
/** @var AuthenticatorData $authenticatorData */
$authenticatorData = $publicKeyCredential->getResponse()->getAttestationObject()->getAuthData();

/** @var AttestationStatement $attestationStatement */
$attestationStatement = $publicKeyCredential->getResponse()->getAttestationObject()->getAttStmt();
static::assertEquals(AttestationStatement::TYPE_ANONCA, $attestationStatement->getType());

static::assertEquals(hex2bin('3ddc4710e9c088b229dba89d563220bb39f7229aff465b0a656b1afb9a8af8a0'), $authenticatorData->getRpIdHash());
static::assertTrue($authenticatorData->isUserPresent());
static::assertTrue($authenticatorData->isUserVerified());
Expand Down

0 comments on commit 572e239

Please sign in to comment.