Parser   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 34
c 0
b 0
f 0
dl 0
loc 92
rs 10
wmc 14

3 Methods

Rating   Name   Duplication   Size   Complexity  
B parse() 0 51 11
A parseKey() 0 5 1
A __construct() 0 4 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Mdanter\Ecc\Serializer\PublicKey\Der;
5
6
use FG\ASN1\ASNObject;
7
use FG\ASN1\Identifier;
8
use FG\ASN1\Universal\Sequence;
9
use Mdanter\Ecc\Crypto\Key\PublicKeyInterface;
10
use Mdanter\Ecc\Math\GmpMathInterface;
11
use Mdanter\Ecc\Serializer\Util\CurveOidMapper;
12
use Mdanter\Ecc\Primitives\GeneratorPoint;
13
use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
14
use Mdanter\Ecc\Serializer\Point\PointSerializerInterface;
15
use Mdanter\Ecc\Serializer\Point\UncompressedPointSerializer;
16
use Mdanter\Ecc\Crypto\Key\PublicKey;
17
18
class Parser
19
{
20
21
    /**
22
     * @var GmpMathInterface
23
     */
24
    private $adapter;
25
26
    /**
27
     * @var UncompressedPointSerializer
28
     */
29
    private $pointSerializer;
30
31
    /**
32
     * Parser constructor.
33
     * @param GmpMathInterface $adapter
34
     * @param PointSerializerInterface|null $pointSerializer
35
     */
36
    public function __construct(GmpMathInterface $adapter, PointSerializerInterface $pointSerializer = null)
37
    {
38
        $this->adapter = $adapter;
39
        $this->pointSerializer = $pointSerializer ?: new UncompressedPointSerializer();
40
    }
41
42
    /**
43
     * @param string $binaryData
44
     * @return PublicKeyInterface
45
     * @throws \FG\ASN1\Exception\ParserException
46
     */
47
    public function parse(string $binaryData): PublicKeyInterface
48
    {
49
        $asnObject = ASNObject::fromBinary($binaryData);
50
        if ($asnObject->getType() !== Identifier::SEQUENCE) {
51
            throw new \RuntimeException('Invalid data.');
52
        }
53
54
        /** @var Sequence $asnObject */
55
        if ($asnObject->getNumberofChildren() != 2) {
56
            throw new \RuntimeException('Invalid data.');
57
        }
58
59
        $children = $asnObject->getChildren();
60
        if (count($children) != 2) {
61
            throw new \RuntimeException('Invalid data.');
62
        }
63
64
        if (count($children) != 2) {
65
            throw new \RuntimeException('Invalid data.');
66
        }
67
68
        if ($children[0]->getType() !== Identifier::SEQUENCE) {
69
            throw new \RuntimeException('Invalid data.');
70
        }
71
72
        if (count($children[0]->getChildren()) != 2) {
0 ignored issues
show
Bug introduced by
The method getChildren() does not exist on FG\ASN1\ASNObject. It seems like you code against a sub-type of FG\ASN1\ASNObject such as FG\ASN1\Construct. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

72
        if (count($children[0]->/** @scrutinizer ignore-call */ getChildren()) != 2) {
Loading history...
73
            throw new \RuntimeException('Invalid data.');
74
        }
75
76
        if ($children[0]->getChildren()[0]->getType() !== Identifier::OBJECT_IDENTIFIER) {
77
            throw new \RuntimeException('Invalid data.');
78
        }
79
80
        if ($children[0]->getChildren()[1]->getType() !== Identifier::OBJECT_IDENTIFIER) {
81
            throw new \RuntimeException('Invalid data.');
82
        }
83
84
        if ($children[1]->getType() !== Identifier::BITSTRING) {
85
            throw new \RuntimeException('Invalid data.');
86
        }
87
88
        $oid = $children[0]->getChildren()[0];
89
        $curveOid = $children[0]->getChildren()[1];
90
        $encodedKey = $children[1];
91
        if ($oid->getContent() !== DerPublicKeySerializer::X509_ECDSA_OID) {
92
            throw new \RuntimeException('Invalid data: non X509 data.');
93
        }
94
95
        $generator = CurveOidMapper::getGeneratorFromOid($curveOid);
96
97
        return $this->parseKey($generator, $encodedKey->getContent());
98
    }
99
100
    /**
101
     * @param GeneratorPoint $generator
102
     * @param string $data
103
     * @return PublicKeyInterface
104
     */
105
    public function parseKey(GeneratorPoint $generator, string $data): PublicKeyInterface
106
    {
107
        $point = $this->pointSerializer->unserialize($generator->getCurve(), $data);
108
109
        return new PublicKey($this->adapter, $generator, $point);
110
    }
111
}
112