Passed
Pull Request — master (#42)
by Stefan
07:12
created

WebAuthnAuthenticationEvent::validateSignature()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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