WebAuthnAuthenticationEvent::validateSignature()   B
last analyzed

Complexity

Conditions 6
Paths 18

Size

Total Lines 32
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 25
c 1
b 0
f 0
dl 0
loc 32
rs 8.8977
cc 6
nc 18
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\webauthn\WebAuthn;
6
7
use Cose\Key\Ec2Key;
8
use Cose\Key\RsaKey;
9
10
/**
11
 * FIDO2/WebAuthn Authentication Processing filter
12
 *
13
 * Filter for registering or authenticating with a FIDO2/WebAuthn token after
14
 * having authenticated with the primary authsource.
15
 *
16
 * @author Stefan Winter <[email protected]>
17
 * @package SimpleSAMLphp
18
 */
19
class WebAuthnAuthenticationEvent extends WebAuthnAbstractEvent
20
{
21
    /**
22
     * Initialize the event object.
23
     *
24
     * Validates and parses the configuration.
25
     *
26
     * @param string $pubkeyCredType  PublicKeyCredential.type
27
     * @param string $scope           the scope of the event
28
     * @param string $challenge       the challenge which was used to trigger this event
29
     * @param string $authData        the authData binary string
30
     * @param string $clientDataJSON  the client data JSON string which is present in all types of events
31
     * @param string $credentialId    the credential ID
32
     * @param string $publicKey       the public key which is supposed to validate the sig
33
     *                                (COSE format, still needs to be converted to PEM!)
34
     * @param string $signature       the signature value to verify
35
     * @param bool $debugMode         print debugging statements?
36
     */
37
    public function __construct(
38
        string $pubkeyCredType,
39
        string $scope,
40
        string $challenge,
41
        string $authData,
42
        string $clientDataJSON,
43
        string $credentialId,
44
        string $publicKey,
45
        int $algo,
46
        string $signature,
47
        bool $debugMode = false,
48
    ) {
49
        $this->eventType = "AUTH";
50
        $this->credential = $publicKey;
51
        $this->algo = $algo;
52
        $this->credentialId = $credentialId;
53
        parent::__construct($pubkeyCredType, $scope, $challenge, $authData, $clientDataJSON, $debugMode);
54
        $this->validateSignature($authData . $this->clientDataHash, $signature);
55
    }
56
57
    /**
58
     * @param string $sigData
59
     * @param string $signature
60
     * @return void
61
     */
62
    private function validateSignature(string $sigData, string $signature): void
63
    {
64
        $keyArray = $this->cborDecode(hex2bin($this->credential));
65
        $keyObject = null;
66
        switch ($this->algo) {
67
            case WebAuthnRegistrationEvent::PK_ALGORITHM_ECDSA:
68
                $keyObject = new Ec2Key($keyArray);
69
                break;
70
            case WebAuthnRegistrationEvent::PK_ALGORITHM_RSA:
71
                $keyObject = new RsaKey($keyArray);
72
                break;
73
            default:
74
                $this->fail("Incoming public key algorithm unknown and not supported!");
75
        }
76
        $keyResource = openssl_pkey_get_public($keyObject->asPEM());
77
        if ($keyResource === false) {
78
            $this->fail("Unable to construct public key resource from PEM (was algo type " . $this->algo . ").");
79
        }
80
        /**
81
         * §7.2 STEP 17: validate signature
82
         */
83
        $sigcheck = openssl_verify($sigData, $signature, $keyResource, OPENSSL_ALGO_SHA256);
84
        switch ($sigcheck) {
85
            case 1:
86
                $this->pass("Signature validation succeeded!");
87
                break;
88
            case 0:
89
                $this->fail("Signature validation failed (sigdata = $sigData) (signature = $signature) !");
90
                break;
91
            default:
92
                $this->fail("There was an error executing the signature check.");
93
                break;
94
        }
95
    }
96
}
97