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.

PublicKeyInfo::publicKey()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 4
nop 0
dl 0
loc 18
ccs 10
cts 10
cp 1
crap 4
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\CryptoTypes\Asymmetric;
6
7
use Sop\ASN1\Type\Constructed\Sequence;
8
use Sop\ASN1\Type\Primitive\BitString;
9
use Sop\ASN1\Type\UnspecifiedType;
10
use Sop\CryptoEncoding\PEM;
11
use Sop\CryptoTypes\AlgorithmIdentifier\AlgorithmIdentifier;
12
use Sop\CryptoTypes\AlgorithmIdentifier\Asymmetric\ECPublicKeyAlgorithmIdentifier;
13
use Sop\CryptoTypes\AlgorithmIdentifier\Feature\AlgorithmIdentifierType;
14
15
/**
16
 * Implements X.509 SubjectPublicKeyInfo ASN.1 type.
17
 *
18
 * @see https://tools.ietf.org/html/rfc5280#section-4.1
19
 */
20
class PublicKeyInfo
21
{
22
    /**
23
     * Algorithm identifier.
24
     *
25
     * @var AlgorithmIdentifierType
26
     */
27
    protected $_algo;
28
29
    /**
30
     * Public key data.
31
     *
32
     * @var string
33
     */
34
    protected $_publicKeyData;
35
36
    /**
37
     * Constructor.
38
     *
39
     * @param AlgorithmIdentifierType $algo Algorithm
40
     * @param string                  $key  Public key data
41
     */
42 18
    public function __construct(AlgorithmIdentifierType $algo, string $key)
43
    {
44 18
        $this->_algo = $algo;
45 18
        $this->_publicKeyData = $key;
46 18
    }
47
48
    /**
49
     * Initialize from ASN.1.
50
     *
51
     * @param Sequence $seq
52
     *
53
     * @return self
54
     */
55 13
    public static function fromASN1(Sequence $seq): self
56
    {
57 13
        $algo = AlgorithmIdentifier::fromASN1($seq->at(0)->asSequence());
58 13
        $key = $seq->at(1)->asBitString()->string();
59 13
        return new self($algo, $key);
60
    }
61
62
    /**
63
     * Inititalize from a PublicKey.
64
     *
65
     * @param PublicKey $public_key
66
     *
67
     * @return self
68
     */
69 7
    public static function fromPublicKey(PublicKey $public_key): self
70
    {
71 7
        return new self($public_key->algorithmIdentifier(),
72 6
            $public_key->subjectPublicKeyData());
73
    }
74
75
    /**
76
     * Initialize from PEM.
77
     *
78
     * @param PEM $pem
79
     *
80
     * @throws \UnexpectedValueException
81
     *
82
     * @return self
83
     */
84 7
    public static function fromPEM(PEM $pem): self
85
    {
86 7
        switch ($pem->type()) {
87 7
            case PEM::TYPE_PUBLIC_KEY:
88 5
                return self::fromDER($pem->data());
89 2
            case PEM::TYPE_RSA_PUBLIC_KEY:
90 1
                return RSA\RSAPublicKey::fromDER($pem->data())->publicKeyInfo();
91
        }
92 1
        throw new \UnexpectedValueException('Invalid PEM type.');
93
    }
94
95
    /**
96
     * Initialize from DER data.
97
     *
98
     * @param string $data
99
     *
100
     * @return self
101
     */
102 12
    public static function fromDER(string $data): self
103
    {
104 12
        return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence());
105
    }
106
107
    /**
108
     * Get algorithm identifier.
109
     *
110
     * @return AlgorithmIdentifierType
111
     */
112 14
    public function algorithmIdentifier(): AlgorithmIdentifierType
113
    {
114 14
        return $this->_algo;
115
    }
116
117
    /**
118
     * Get public key data.
119
     *
120
     * @return string
121
     */
122 3
    public function publicKeyData(): string
123
    {
124 3
        return $this->_publicKeyData;
125
    }
126
127
    /**
128
     * Get public key.
129
     *
130
     * @throws \RuntimeException
131
     *
132
     * @return PublicKey
133
     */
134 8
    public function publicKey(): PublicKey
135
    {
136 8
        $algo = $this->algorithmIdentifier();
137 8
        switch ($algo->oid()) {
138
            // RSA
139
            case AlgorithmIdentifier::OID_RSA_ENCRYPTION:
140 3
                return RSA\RSAPublicKey::fromDER($this->_publicKeyData);
141
            // elliptic curve
142
            case AlgorithmIdentifier::OID_EC_PUBLIC_KEY:
143 4
                if (!$algo instanceof ECPublicKeyAlgorithmIdentifier) {
144 1
                    throw new \UnexpectedValueException('Not an EC algorithm.');
145
                }
146
                // ECPoint is directly mapped into public key data
147 3
                return new EC\ECPublicKey($this->_publicKeyData,
148 3
                    $algo->namedCurve());
149
        }
150 1
        throw new \RuntimeException(
151 1
            'Public key ' . $algo->name() . ' not supported.');
152
    }
153
154
    /**
155
     * Get key identifier using method 1 as described by RFC 5280.
156
     *
157
     * @see https://tools.ietf.org/html/rfc5280#section-4.2.1.2
158
     *
159
     * @return string 20 bytes (160 bits) long identifier
160
     */
161 2
    public function keyIdentifier(): string
162
    {
163 2
        return sha1($this->_publicKeyData, true);
164
    }
165
166
    /**
167
     * Get key identifier using method 2 as described by RFC 5280.
168
     *
169
     * @see https://tools.ietf.org/html/rfc5280#section-4.2.1.2
170
     *
171
     * @return string 8 bytes (64 bits) long identifier
172
     */
173 1
    public function keyIdentifier64(): string
174
    {
175 1
        $id = substr($this->keyIdentifier(), -8);
176 1
        $c = (ord($id[0]) & 0x0f) | 0x40;
177 1
        $id[0] = chr($c);
178 1
        return $id;
179
    }
180
181
    /**
182
     * Generate ASN.1 structure.
183
     *
184
     * @return Sequence
185
     */
186 4
    public function toASN1(): Sequence
187
    {
188 4
        return new Sequence($this->_algo->toASN1(),
189 4
            new BitString($this->_publicKeyData));
190
    }
191
192
    /**
193
     * Generate DER encoding.
194
     *
195
     * @return string
196
     */
197 3
    public function toDER(): string
198
    {
199 3
        return $this->toASN1()->toDER();
200
    }
201
202
    /**
203
     * Generate PEM.
204
     *
205
     * @return PEM
206
     */
207 3
    public function toPEM(): PEM
208
    {
209 3
        return new PEM(PEM::TYPE_PUBLIC_KEY, $this->toDER());
210
    }
211
}
212