migrating from u2f-api.js to webauthn

This commit is contained in:
FreddlePat
2022-01-12 21:09:18 +01:00
parent e2b4b6f6bc
commit d1d134038f
42 changed files with 918 additions and 461 deletions

View File

@@ -1,9 +1,9 @@
<?php
namespace WebAuthn\Attestation;
use WebAuthn\WebAuthnException;
use WebAuthn\CBOR\CborDecoder;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\CBOR\CborDecoder;
use lbuchs\WebAuthn\Binary\ByteBuffer;
/**
* @author Lukas Buchs
@@ -12,6 +12,7 @@ use WebAuthn\Binary\ByteBuffer;
class AttestationObject {
private $_authenticatorData;
private $_attestationFormat;
private $_attestationFormatName;
public function __construct($binary , $allowedFormats) {
$enc = CborDecoder::decode($binary);
@@ -29,13 +30,15 @@ class AttestationObject {
}
$this->_authenticatorData = new AuthenticatorData($enc['authData']->getBinaryString());
$this->_attestationFormatName = $enc['fmt'];
// Format ok?
if (!in_array($enc['fmt'], $allowedFormats)) {
throw new WebAuthnException('invalid atttestation format: ' . $enc['fmt'], WebAuthnException::INVALID_DATA);
if (!in_array($this->_attestationFormatName, $allowedFormats)) {
throw new WebAuthnException('invalid atttestation format: ' . $this->_attestationFormatName, WebAuthnException::INVALID_DATA);
}
switch ($enc['fmt']) {
switch ($this->_attestationFormatName) {
case 'android-key': $this->_attestationFormat = new Format\AndroidKey($enc, $this->_authenticatorData); break;
case 'android-safetynet': $this->_attestationFormat = new Format\AndroidSafetyNet($enc, $this->_authenticatorData); break;
case 'apple': $this->_attestationFormat = new Format\Apple($enc, $this->_authenticatorData); break;
@@ -47,6 +50,14 @@ class AttestationObject {
}
}
/**
* returns the attestation format name
* @return string
*/
public function getAttestationFormatName() {
return $this->_attestationFormatName;
}
/**
* returns the attestation public key in PEM format
* @return AuthenticatorData
@@ -72,16 +83,19 @@ class AttestationObject {
$issuer = '';
if ($pem) {
$certInfo = \openssl_x509_parse($pem);
if (\is_array($certInfo) && \is_array($certInfo['issuer'])) {
if ($certInfo['issuer']['CN']) {
$issuer .= \trim($certInfo['issuer']['CN']);
if (\is_array($certInfo) && \array_key_exists('issuer', $certInfo) && \is_array($certInfo['issuer'])) {
$cn = $certInfo['issuer']['CN'] ?? '';
$o = $certInfo['issuer']['O'] ?? '';
$ou = $certInfo['issuer']['OU'] ?? '';
if ($cn) {
$issuer .= $cn;
}
if ($certInfo['issuer']['O'] || $certInfo['issuer']['OU']) {
if ($issuer) {
$issuer .= ' (' . \trim($certInfo['issuer']['O'] . ' ' . $certInfo['issuer']['OU']) . ')';
} else {
$issuer .= \trim($certInfo['issuer']['O'] . ' ' . $certInfo['issuer']['OU']);
}
if ($issuer && ($o || $ou)) {
$issuer .= ' (' . trim($o . ' ' . $ou) . ')';
} else {
$issuer .= trim($o . ' ' . $ou);
}
}
}
@@ -98,16 +112,19 @@ class AttestationObject {
$subject = '';
if ($pem) {
$certInfo = \openssl_x509_parse($pem);
if (\is_array($certInfo) && \is_array($certInfo['subject'])) {
if ($certInfo['subject']['CN']) {
$subject .= \trim($certInfo['subject']['CN']);
if (\is_array($certInfo) && \array_key_exists('subject', $certInfo) && \is_array($certInfo['subject'])) {
$cn = $certInfo['subject']['CN'] ?? '';
$o = $certInfo['subject']['O'] ?? '';
$ou = $certInfo['subject']['OU'] ?? '';
if ($cn) {
$subject .= $cn;
}
if ($certInfo['subject']['O'] || $certInfo['subject']['OU']) {
if ($subject) {
$subject .= ' (' . \trim($certInfo['subject']['O'] . ' ' . $certInfo['subject']['OU']) . ')';
} else {
$subject .= \trim($certInfo['subject']['O'] . ' ' . $certInfo['subject']['OU']);
}
if ($subject && ($o || $ou)) {
$subject .= ' (' . trim($o . ' ' . $ou) . ')';
} else {
$subject .= trim($o . ' ' . $ou);
}
}
}

View File

@@ -1,9 +1,9 @@
<?php
namespace WebAuthn\Attestation;
use WebAuthn\WebAuthnException;
use WebAuthn\CBOR\CborDecoder;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\CBOR\CborDecoder;
use lbuchs\WebAuthn\Binary\ByteBuffer;
/**
* @author Lukas Buchs

View File

@@ -1,15 +1,16 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\Binary\ByteBuffer;
class AndroidKey extends FormatBase {
private $_alg;
private $_signature;
private $_x5c;
public function __construct($AttestionObject, \WebAuthn\Attestation\AuthenticatorData $authenticatorData) {
public function __construct($AttestionObject, AuthenticatorData $authenticatorData) {
parent::__construct($AttestionObject, $authenticatorData);
// check u2f data

View File

@@ -1,9 +1,10 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\Binary\ByteBuffer;
class AndroidSafetyNet extends FormatBase {
private $_signature;
@@ -11,7 +12,7 @@ class AndroidSafetyNet extends FormatBase {
private $_x5c;
private $_payload;
public function __construct($AttestionObject, \WebAuthn\Attestation\AuthenticatorData $authenticatorData) {
public function __construct($AttestionObject, AuthenticatorData $authenticatorData) {
parent::__construct($AttestionObject, $authenticatorData);
// check data

View File

@@ -1,14 +1,15 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\Binary\ByteBuffer;
class Apple extends FormatBase {
private $_x5c;
public function __construct($AttestionObject, \WebAuthn\Attestation\AuthenticatorData $authenticatorData) {
public function __construct($AttestionObject, AuthenticatorData $authenticatorData) {
parent::__construct($AttestionObject, $authenticatorData);
// check packed data

View File

@@ -1,8 +1,9 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
abstract class FormatBase {
@@ -14,9 +15,9 @@ abstract class FormatBase {
/**
*
* @param Array $AttestionObject
* @param \WebAuthn\Attestation\AuthenticatorData $authenticatorData
* @param AuthenticatorData $authenticatorData
*/
public function __construct($AttestionObject, \WebAuthn\Attestation\AuthenticatorData $authenticatorData) {
public function __construct($AttestionObject, AuthenticatorData $authenticatorData) {
$this->_attestationObject = $AttestionObject;
$this->_authenticatorData = $authenticatorData;
}
@@ -26,7 +27,7 @@ abstract class FormatBase {
*/
public function __destruct() {
// delete X.509 chain certificate file after use
if (\is_file($this->_x5c_tempFile)) {
if ($this->_x5c_tempFile && \is_file($this->_x5c_tempFile)) {
\unlink($this->_x5c_tempFile);
}
}
@@ -36,7 +37,7 @@ abstract class FormatBase {
* @return string|null
*/
public function getCertificateChain() {
if (\is_file($this->_x5c_tempFile)) {
if ($this->_x5c_tempFile && \is_file($this->_x5c_tempFile)) {
return \file_get_contents($this->_x5c_tempFile);
}
return null;

View File

@@ -1,13 +1,14 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
use lbuchs\WebAuthn\WebAuthnException;
class None extends FormatBase {
public function __construct($AttestionObject, \WebAuthn\Attestation\AuthenticatorData $authenticatorData) {
public function __construct($AttestionObject, AuthenticatorData $authenticatorData) {
parent::__construct($AttestionObject, $authenticatorData);
}
@@ -28,12 +29,13 @@ class None extends FormatBase {
}
/**
* validates the certificate against root certificates
* validates the certificate against root certificates.
* Format 'none' does not contain any ca, so always false.
* @param array $rootCas
* @return boolean
* @throws WebAuthnException
*/
public function validateRootCertificate($rootCas) {
return true;
return false;
}
}

View File

@@ -1,16 +1,17 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\Binary\ByteBuffer;
class Packed extends FormatBase {
private $_alg;
private $_signature;
private $_x5c;
public function __construct($AttestionObject, \WebAuthn\Attestation\AuthenticatorData $authenticatorData) {
public function __construct($AttestionObject, AuthenticatorData $authenticatorData) {
parent::__construct($AttestionObject, $authenticatorData);
// check packed data

View File

@@ -1,9 +1,10 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\Binary\ByteBuffer;
class Tpm extends FormatBase {
private $_TPM_GENERATED_VALUE = "\xFF\x54\x43\x47";
@@ -19,7 +20,7 @@ class Tpm extends FormatBase {
private $_certInfo;
public function __construct($AttestionObject, \WebAuthn\Attestation\AuthenticatorData $authenticatorData) {
public function __construct($AttestionObject, AuthenticatorData $authenticatorData) {
parent::__construct($AttestionObject, $authenticatorData);
// check packed data

View File

@@ -1,9 +1,10 @@
<?php
namespace WebAuthn\Attestation\Format;
use WebAuthn\WebAuthnException;
use WebAuthn\Binary\ByteBuffer;
namespace lbuchs\WebAuthn\Attestation\Format;
use lbuchs\WebAuthn\Attestation\AuthenticatorData;
use lbuchs\WebAuthn\WebAuthnException;
use lbuchs\WebAuthn\Binary\ByteBuffer;
class U2f extends FormatBase {
private $_alg = -7;