Issues (139)

Serializer/PrivateKey/DerPrivateKeySerializer.php (1 issue)

Labels
Severity
1
<?php
2
declare(strict_types=1);
3
4
namespace Mdanter\Ecc\Serializer\PrivateKey;
5
6
use FG\ASN1\ASNObject;
7
use FG\ASN1\Universal\Sequence;
8
use FG\ASN1\Universal\Integer;
9
use FG\ASN1\Universal\BitString;
10
use FG\ASN1\Universal\OctetString;
11
use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface;
12
use Mdanter\Ecc\Math\GmpMathInterface;
13
use Mdanter\Ecc\Math\MathAdapterFactory;
14
use Mdanter\Ecc\Serializer\Util\CurveOidMapper;
15
use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
16
use FG\ASN1\ExplicitlyTaggedObject;
17
18
/**
19
 * PEM Private key formatter
20
 *
21
 * @link https://tools.ietf.org/html/rfc5915
22
 */
23
class DerPrivateKeySerializer implements PrivateKeySerializerInterface
24
{
25
26
    const VERSION = 1;
27
28
    /**
29
     * @var GmpMathInterface|null
30
     */
31
    private $adapter;
32
33
    /**
34
     * @var DerPublicKeySerializer
35
     */
36
    private $pubKeySerializer;
37
38
    /**
39
     * @param GmpMathInterface       $adapter
40
     * @param DerPublicKeySerializer $pubKeySerializer
41
     */
42
    public function __construct(GmpMathInterface $adapter = null, DerPublicKeySerializer $pubKeySerializer = null)
43
    {
44
        $this->adapter = $adapter ?: MathAdapterFactory::getAdapter();
45
        $this->pubKeySerializer = $pubKeySerializer ?: new DerPublicKeySerializer($this->adapter);
46
    }
47
48
    /**
49
     * {@inheritDoc}
50
     * @see \Mdanter\Ecc\Serializer\PrivateKey\PrivateKeySerializerInterface::serialize()
51
     */
52
    public function serialize(PrivateKeyInterface $key): string
53
    {
54
        $privateKeyInfo = new Sequence(
55
            new Integer(self::VERSION),
56
            new OctetString($this->formatKey($key)),
57
            new ExplicitlyTaggedObject(0, CurveOidMapper::getCurveOid($key->getPoint()->getCurve())),
58
            new ExplicitlyTaggedObject(1, $this->encodePubKey($key))
59
        );
60
61
        return $privateKeyInfo->getBinary();
62
    }
63
64
    /**
65
     * @param PrivateKeyInterface $key
66
     * @return BitString
67
     */
68
    private function encodePubKey(PrivateKeyInterface $key): BitString
69
    {
70
        return new BitString(
71
            $this->pubKeySerializer->getUncompressedKey($key->getPublicKey())
72
        );
73
    }
74
75
    /**
76
     * @param PrivateKeyInterface $key
77
     * @return string
78
     */
79
    private function formatKey(PrivateKeyInterface $key): string
80
    {
81
        return gmp_strval($key->getSecret(), 16);
82
    }
83
84
    /**
85
     * {@inheritDoc}
86
     * @see \Mdanter\Ecc\Serializer\PrivateKey\PrivateKeySerializerInterface::parse()
87
     * @throws \FG\ASN1\Exception\ParserException
88
     */
89
    public function parse(string $data): PrivateKeyInterface
90
    {
91
        $asnObject = ASNObject::fromBinary($data);
92
93
        if (! ($asnObject instanceof Sequence) || $asnObject->getNumberofChildren() !== 4) {
94
            throw new \RuntimeException('Invalid data.');
95
        }
96
97
        $children = $asnObject->getChildren();
98
99
        $version = $children[0];
100
101
        if ($version->getContent() != 1) {
102
            throw new \RuntimeException('Invalid data: only version 1 (RFC5915) keys are supported.');
103
        }
104
105
        $key = gmp_init($children[1]->getContent(), 16);
106
        $oid = $children[2]->getContent()[0];
107
        $generator = CurveOidMapper::getGeneratorFromOid($oid);
108
109
        return $generator->getPrivateKeyFrom($key);
0 ignored issues
show
It seems like $key can also be of type resource; however, parameter $secretMultiplier of Mdanter\Ecc\Primitives\G...nt::getPrivateKeyFrom() does only seem to accept GMP, maybe add an additional type check? ( Ignorable by Annotation )

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

109
        return $generator->getPrivateKeyFrom(/** @scrutinizer ignore-type */ $key);
Loading history...
110
    }
111
}
112