GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ECPrivateKey::fromASN1()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 5
nop 1
dl 0
loc 17
ccs 13
cts 13
cp 1
crap 4
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\CryptoTypes\Asymmetric\EC;
6
7
use Sop\ASN1\Type\Constructed\Sequence;
8
use Sop\ASN1\Type\Primitive\BitString;
9
use Sop\ASN1\Type\Primitive\Integer;
10
use Sop\ASN1\Type\Primitive\ObjectIdentifier;
11
use Sop\ASN1\Type\Primitive\OctetString;
12
use Sop\ASN1\Type\Tagged\ExplicitlyTaggedType;
13
use Sop\ASN1\Type\UnspecifiedType;
14
use Sop\CryptoEncoding\PEM;
15
use Sop\CryptoTypes\AlgorithmIdentifier\Asymmetric\ECPublicKeyAlgorithmIdentifier;
16
use Sop\CryptoTypes\AlgorithmIdentifier\Feature\AlgorithmIdentifierType;
17
use Sop\CryptoTypes\Asymmetric\PrivateKey;
18
use Sop\CryptoTypes\Asymmetric\PublicKey;
19
20
/**
21
 * Implements elliptic curve private key type as specified by RFC 5915.
22
 *
23
 * @see https://tools.ietf.org/html/rfc5915#section-3
24
 */
25
class ECPrivateKey extends PrivateKey
26
{
27
    /**
28
     * Private key.
29
     *
30
     * @var string
31
     */
32
    protected $_privateKey;
33
34
    /**
35
     * Named curve OID.
36
     *
37
     * @var null|string
38
     */
39
    protected $_namedCurve;
40
41
    /**
42
     * ECPoint value.
43
     *
44
     * @var null|string
45
     */
46
    protected $_publicKey;
47
48
    /**
49
     * Constructor.
50
     *
51
     * @param string      $private_key Private key
52
     * @param null|string $named_curve OID of the named curve
53
     * @param null|string $public_key  ECPoint value
54
     */
55 11
    public function __construct(string $private_key, ?string $named_curve = null,
56
        ?string $public_key = null)
57
    {
58 11
        $this->_privateKey = $private_key;
59 11
        $this->_namedCurve = $named_curve;
60 11
        $this->_publicKey = $public_key;
61 11
    }
62
63
    /**
64
     * Initialize from ASN.1.
65
     *
66
     * @param Sequence $seq
67
     *
68
     * @throws \UnexpectedValueException
69
     *
70
     * @return self
71
     */
72 11
    public static function fromASN1(Sequence $seq): ECPrivateKey
73
    {
74 11
        $version = $seq->at(0)->asInteger()->intNumber();
75 11
        if (1 !== $version) {
76 1
            throw new \UnexpectedValueException('Version must be 1.');
77
        }
78 10
        $private_key = $seq->at(1)->asOctetString()->string();
79 10
        $named_curve = null;
80 10
        if ($seq->hasTagged(0)) {
81 4
            $params = $seq->getTagged(0)->asExplicit();
82 4
            $named_curve = $params->asObjectIdentifier()->oid();
83
        }
84 10
        $public_key = null;
85 10
        if ($seq->hasTagged(1)) {
86 10
            $public_key = $seq->getTagged(1)->asExplicit()->asBitString()->string();
87
        }
88 10
        return new self($private_key, $named_curve, $public_key);
89
    }
90
91
    /**
92
     * Initialize from DER data.
93
     *
94
     * @param string $data
95
     *
96
     * @return self
97
     */
98 10
    public static function fromDER(string $data): ECPrivateKey
99
    {
100 10
        return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence());
101
    }
102
103
    /**
104
     * @see PrivateKey::fromPEM()
105
     *
106
     * @param PEM $pem
107
     *
108
     * @throws \UnexpectedValueException
109
     *
110
     * @return self
111
     */
112 4
    public static function fromPEM(PEM $pem): ECPrivateKey
113
    {
114 4
        $pk = parent::fromPEM($pem);
115 3
        if (!($pk instanceof self)) {
116 1
            throw new \UnexpectedValueException('Not an EC private key.');
117
        }
118 2
        return $pk;
119
    }
120
121
    /**
122
     * Get the EC private key value.
123
     *
124
     * @return string Octets of the private key
125
     */
126 1
    public function privateKeyOctets(): string
127
    {
128 1
        return $this->_privateKey;
129
    }
130
131
    /**
132
     * Whether named curve is present.
133
     *
134
     * @return bool
135
     */
136 14
    public function hasNamedCurve(): bool
137
    {
138 14
        return isset($this->_namedCurve);
139
    }
140
141
    /**
142
     * Get named curve OID.
143
     *
144
     * @throws \LogicException
145
     *
146
     * @return string
147
     */
148 9
    public function namedCurve(): string
149
    {
150 9
        if (!$this->hasNamedCurve()) {
151 1
            throw new \LogicException('namedCurve not set.');
152
        }
153 8
        return $this->_namedCurve;
154
    }
155
156
    /**
157
     * Get self with named curve.
158
     *
159
     * @param null|string $named_curve Named curve OID
160
     *
161
     * @return self
162
     */
163 6
    public function withNamedCurve(?string $named_curve): ECPrivateKey
164
    {
165 6
        $obj = clone $this;
166 6
        $obj->_namedCurve = $named_curve;
167 6
        return $obj;
168
    }
169
170
    /**
171
     * {@inheritdoc}
172
     */
173 2
    public function algorithmIdentifier(): AlgorithmIdentifierType
174
    {
175 2
        return new ECPublicKeyAlgorithmIdentifier($this->namedCurve());
176
    }
177
178
    /**
179
     * Whether public key is present.
180
     *
181
     * @return bool
182
     */
183 3
    public function hasPublicKey(): bool
184
    {
185 3
        return isset($this->_publicKey);
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     *
191
     * @return ECPublicKey
192
     */
193 3
    public function publicKey(): PublicKey
194
    {
195 3
        if (!$this->hasPublicKey()) {
196 1
            throw new \LogicException('publicKey not set.');
197
        }
198 2
        return new ECPublicKey($this->_publicKey, $this->namedCurve());
199
    }
200
201
    /**
202
     * Generate ASN.1 structure.
203
     *
204
     * @return Sequence
205
     */
206 3
    public function toASN1(): Sequence
207
    {
208 3
        $elements = [new Integer(1), new OctetString($this->_privateKey)];
209 3
        if (isset($this->_namedCurve)) {
210 3
            $elements[] = new ExplicitlyTaggedType(0,
211 3
                new ObjectIdentifier($this->_namedCurve));
212
        }
213 3
        if (isset($this->_publicKey)) {
214 3
            $elements[] = new ExplicitlyTaggedType(1,
215 3
                new BitString($this->_publicKey));
216
        }
217 3
        return new Sequence(...$elements);
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223 3
    public function toDER(): string
224
    {
225 3
        return $this->toASN1()->toDER();
226
    }
227
228
    /**
229
     * {@inheritdoc}
230
     */
231 1
    public function toPEM(): PEM
232
    {
233 1
        return new PEM(PEM::TYPE_EC_PRIVATE_KEY, $this->toDER());
234
    }
235
}
236