Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/WebAuthn.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class WebAuthn {
private $_signatureCounter;
private $_caFiles;
private $_formats;
private $_androidKeyHashes;

/**
* Initialize a new WebAuthn server
Expand Down Expand Up @@ -90,6 +91,23 @@ public function addRootCertificates($path, $certFileExtensions=null) {
}
}

/**
* add key hashes for android verification
* @param array<string> $hashes
* @return void
*/
public function addAndroidKeyHashes($hashes) {
if (!\is_array($this->_androidKeyHashes)) {
$this->_androidKeyHashes = [];
}

foreach ($hashes as $hash) {
if (is_string($hash)) {
$this->_androidKeyHashes[] = $hash;
}
}
}

/**
* Returns the generated challenge to save for later validation
* @return ByteBuffer
Expand Down Expand Up @@ -603,6 +621,10 @@ public function queryFidoMetaDataService($certFolder, $deleteCerts=true) {
* @throws WebAuthnException
*/
private function _checkOrigin($origin) {
if (str_starts_with($origin, 'android:apk-key-hash:')) {
return $this->_checkAndroidKeyHashes($origin);
}

// https://www.w3.org/TR/webauthn/#rp-id

// The origin's scheme must be https
Expand All @@ -619,6 +641,19 @@ private function _checkOrigin($origin) {
return \preg_match('/' . \preg_quote($this->_rpId) . '$/i', $host) === 1;
}

/**
* checks if the origin value contains a known android key hash
* @param string $origin
* @return boolean
*/
private function _checkAndroidKeyHashes($origin) {
$parts = explode('android:apk-key-hash:', $origin);
if (count($parts) !== 2) {
return false;
}
return in_array($parts[1], $this->_androidKeyHashes, true);
}

/**
* generates a new challange
* @param int $length
Expand Down