Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
Backport cid_pubkey fix to 2.0/master (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
Firehed committed Jun 13, 2019
1 parent 6526b8a commit a8c8734
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 25 deletions.
25 changes: 9 additions & 16 deletions src/ClientData.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

namespace Firehed\U2F;

use JsonSerializable;
use Firehed\U2F\InvalidDataException as IDE;

class ClientData implements JsonSerializable
class ClientData
{
use ChallengeTrait;

/** @var string */
private $originalJson;
private $cid_pubkey;
private $origin;
private $typ;
Expand All @@ -24,7 +25,11 @@ public static function fromJson(string $json)
$ret->setType($ret->validateKey('typ', $data));
$ret->setChallenge($ret->validateKey('challenge', $data));
$ret->origin = $ret->validateKey('origin', $data);
$ret->cid_pubkey = $ret->validateKey('cid_pubkey', $data);
// This field is optional
if (isset($data['cid_pubkey'])) {
$ret->cid_pubkey = $data['cid_pubkey'];
}
$ret->originalJson = $json;
return $ret;
}

Expand Down Expand Up @@ -72,18 +77,6 @@ private function validateKey(string $key, array $data)
// Returns the SHA256 hash of this object per the raw message formats spec
public function getChallengeParameter(): string
{
$json = json_encode($this, \JSON_UNESCAPED_SLASHES);
assert($json !== false);
return hash('sha256', $json, true);
}

public function jsonSerialize()
{
return [
'typ' => $this->typ,
'challenge' => $this->getChallenge(),
'origin' => $this->origin,
'cid_pubkey' => $this->cid_pubkey,
];
return hash('sha256', $this->originalJson, true);
}
}
13 changes: 4 additions & 9 deletions tests/ClientDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public function testFromValidJson()

/**
* @covers ::getChallengeParameter
* @covers ::jsonSerialize
*/
public function testGetChallengeParameter()
{
Expand All @@ -42,13 +41,10 @@ public function testGetChallengeParameter()
'Test vector should have been 32 bytes'
);

$goodData = [
'typ' => 'navigator.id.finishEnrollment',
'challenge' => 'PfsWR1Umy2V5Al1Bam2tG0yfPLeJElfwRzzAzkYPgzo',
'origin' => 'https://u2f.ericstern.com',
'cid_pubkey' => '',
];
$goodJson = json_encode($goodData);
$goodJson = '{"typ":"navigator.id.finishEnrollment","challenge":"PfsWR'.
'1Umy2V5Al1Bam2tG0yfPLeJElfwRzzAzkYPgzo","origin":"https://u2f.eri'.
'cstern.com","cid_pubkey":""}';

assert($goodJson !== false);
$clientData = ClientData::fromJson($goodJson);
$this->assertTrue(
Expand Down Expand Up @@ -139,7 +135,6 @@ public function missingData(): array
$without('typ'),
$without('challenge'),
$without('origin'),
$without('cid_pubkey'),
];
}

Expand Down
66 changes: 66 additions & 0 deletions tests/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,72 @@ public function testAuthenticateThrowsIfRequestIsSignedWithWrongKey()
->authenticate($response);
}

// -( Alternate formats (see #14) )----------------------------------------

public function testRegistrationWithoutCidPubkeyBug14Case1()
{
$server = (new Server())
->disableCAVerification()
->setAppId('https://u2f.ericstern.com');

$registerRequest = new RegisterRequest();
$registerRequest->setAppId($server->getAppId())
->setChallenge('dNqjowssvlxx9zBhvsy03A');
$server->setRegisterRequest($registerRequest);

$json = '{"registrationData":"BQSFDYsZaHlRBQcdLyu4jZ-Bukb1vw6QtSfmvTQO'.
'IXpjZpfqYptdtpBznuNBslzlZdodspfqRkqwJIt3a0W2P_HlQImHG1FoSkYdPwSzp'.
'3WvlDisShW5fveiaaI4Zk8oZBkyWoQ6v1c2ypcd5OWPX6rAH-N7cPjw1Vg_w1q_YL'.
'c3mR8wggE0MIHboAMCAQICCjJ1rwmwx867ew8wCgYIKoZIzj0EAwIwFTETMBEGA1U'.
'EAxMKVTJGIElzc3VlcjAaFwswMDAxMDEwMDAwWhcLMDAwMTAxMDAwMFowFTETMBEG'.
'A1UEAxMKVTJGIERldmljZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCLzJT4vt'.
'kl-799Ks5wINHdVRIKCLq-kX6oIajh_2Dv4Sk0cBVteQt1xdGau1XzEaGYIOvU5hU'.
'm2J2pxVBQIzaajFzAVMBMGCysGAQQBguUcAgEBBAQDAgUgMAoGCCqGSM49BAMCA0g'.
'AMEUCIQDBo6aOLxanIUYnBX9iu3KMngPnobpi0EZSTkVtLC8_cwIgC1945RGqGBKf'.
'byNtkhMifZK05n7fU-gW37Bdnci5D94wRQIgEPJVWZ7zgVQUctG3xpWBv77s3u2R7'.
'OJP-UjkWdcUs2QCIQC1fqlZIrl4kIEsSQTRMauvcaoeunV-I24WYnp3rgC_Dg","v'.
'ersion":"U2F_V2","challenge":"dNqjowssvlxx9zBhvsy03A","appId":"ht'.
'tps:https://u2f.ericstern.com","clientData":"eyJjaGFsbGVuZ2UiOiJkTnFqb3'.
'dzc3ZseHg5ekJodnN5MDNBIiwib3JpZ2luIjoiaHR0cHM6Ly91MmYuZXJpY3N0ZXJ'.
'uLmNvbSIsInR5cCI6Im5hdmlnYXRvci5pZC5maW5pc2hFbnJvbGxtZW50In0"}';
$registerResponse = RegisterResponse::fromJson($json);

$registration = $server->register($registerResponse);
$this->assertInstanceOf(Registration::class, $registration);
}

public function testRegistrationWithoutCidPubkeyBug14Case2()
{
$server = (new Server())
->disableCAVerification()
->setAppId('https://u2f.ericstern.com');

$registerRequest = new RegisterRequest();
$registerRequest->setAppId($server->getAppId())
->setChallenge('E23usdC7VkxjN1mwRAeyjg');
$server->setRegisterRequest($registerRequest);

$json = '{"registrationData":"BQSTffB-e9hdFwhsfb2t-2ppwyxZAltnDf6TYwv4'.
'1VtleEO4488JwNFGr_bks_4EzA4DoluDBCgfmULGpZpXykTZQMOMz9DfbESHnuBY9'.
'cmTxVTVtrsTFTQA-IPETCYJ2dYACULXRN7_qLq_2WnDQJaME7zWyZEB0NFu-hosav'.
'uqjncwggEbMIHCoAMCAQICCiIygbKxS2KpYY8wCgYIKoZIzj0EAwIwFTETMBEGA1U'.
'EAxMKVTJGIElzc3VlcjAaFwswMDAxMDEwMDAwWhcLMDAwMTAxMDAwMFowFTETMBEG'.
'A1UEAxMKVTJGIERldmljZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCdqjfpHR'.
'9L8a6-pVRv9PWu-pORC9sO9eDk6ZlFIXaclyfxbLJqAehvIWJuzij_BxJOLbQPD_9'.
'fX5uKh9tDv8nowCgYIKoZIzj0EAwIDSAAwRQIhAMGjpo4vFqchRicFf2K7coyeA-e'.
'humLQRlJORW0sLz9zAiALX3jlEaoYEp9vI22SEyJ9krTmft9T6BbfsF2dyLkP3jBE'.
'AiAHD70-wA4f3SZk6s0RocHAA4nDCGaVFvTBG4gZXcZTnQIge2joenpQxVP0r1o9E'.
'zL9C3aR-HEKhSHr86MX4eUTMlw","version":"U2F_V2","challenge":"E23us'.
'dC7VkxjN1mwRAeyjg","appId":"https://u2f.ericstern.com","clientDat'.
'a":"eyJjaGFsbGVuZ2UiOiJFMjN1c2RDN1ZreGpOMW13UkFleWpnIiwib3JpZ2luI'.
'joiaHR0cHM6Ly91MmYuZXJpY3N0ZXJuLmNvbSIsInR5cCI6Im5hdmlnYXRvci5pZC'.
'5maW5pc2hFbnJvbGxtZW50In0"}';
$registerResponse = RegisterResponse::fromJson($json);

$registration = $server->register($registerResponse);
$this->assertInstanceOf(Registration::class, $registration);
}

// -( Helpers )------------------------------------------------------------

private function getDefaultRegisterRequest(): RegisterRequest
Expand Down

0 comments on commit a8c8734

Please sign in to comment.