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.
Passed
Push — master ( 035734...405cf3 )
by Joni
28:16
created

Extension::_extnValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace X509\Certificate\Extension;
5
6
use ASN1\Element;
7
use ASN1\Type\Constructed\Sequence;
8
use ASN1\Type\Primitive\Boolean;
9
use ASN1\Type\Primitive\ObjectIdentifier;
10
use ASN1\Type\Primitive\OctetString;
11
12
/**
13
 * Base class for certificate extensions.
14
 *
15
 * @link https://tools.ietf.org/html/rfc5280#section-4.2
16
 * @link https://tools.ietf.org/html/rfc5280#section-4.1
17
 */
18
abstract class Extension
19
{
20
    // OID's from standard certificate extensions
21
    const OID_OBSOLETE_AUTHORITY_KEY_IDENTIFIER = "2.5.29.1";
22
    const OID_OBSOLETE_KEY_ATTRIBUTES = "2.5.29.2";
23
    const OID_OBSOLETE_CERTIFICATE_POLICIES = "2.5.29.3";
24
    const OID_OBSOLETE_KEY_USAGE_RESTRICTION = "2.5.29.4";
25
    const OID_OBSOLETE_POLICY_MAPPING = "2.5.29.5";
26
    const OID_OBSOLETE_SUBTREES_CONSTRAINT = "2.5.29.6";
27
    const OID_OBSOLETE_SUBJECT_ALT_NAME = "2.5.29.7";
28
    const OID_OBSOLETE_ISSUER_ALT_NAME = "2.5.29.8";
29
    const OID_SUBJECT_DIRECTORY_ATTRIBUTES = "2.5.29.9";
30
    const OID_OBSOLETE_BASIC_CONSTRAINTS = "2.5.29.10";
31
    const OID_SUBJECT_KEY_IDENTIFIER = "2.5.29.14";
32
    const OID_KEY_USAGE = "2.5.29.15";
33
    const OID_PRIVATE_KEY_USAGE_PERIOD = "2.5.29.16";
34
    const OID_SUBJECT_ALT_NAME = "2.5.29.17";
35
    const OID_ISSUER_ALT_NAME = "2.5.29.18";
36
    const OID_BASIC_CONSTRAINTS = "2.5.29.19";
37
    const OID_CRL_NUMBER = "2.5.29.20";
38
    const OID_REASON_CODE = "2.5.29.21";
39
    const OID_OBSOLETE_EXPIRATION_DATE = "2.5.29.22";
40
    const OID_INSTRUCTION_CODE = "2.5.29.23";
41
    const OID_INVALIDITY_DATE = "2.5.29.24";
42
    const OID_OBSOLETE_CRL_DISTRIBUTION_POINTS = "2.5.29.25";
43
    const OID_OBSOLETE_ISSUING_DISTRIBUTION_POINT = "2.5.29.26";
44
    const OID_DELTA_CRL_INDICATOR = "2.5.29.27";
45
    const OID_ISSUING_DISTRIBUTION_POINT = "2.5.29.28";
46
    const OID_CERTIFICATE_ISSUER = "2.5.29.29";
47
    const OID_NAME_CONSTRAINTS = "2.5.29.30";
48
    const OID_CRL_DISTRIBUTION_POINTS = "2.5.29.31";
49
    const OID_CERTIFICATE_POLICIES = "2.5.29.32";
50
    const OID_POLICY_MAPPINGS = "2.5.29.33";
51
    const OID_OBSOLETE_POLICY_CONSTRAINTS = "2.5.29.34";
52
    const OID_AUTHORITY_KEY_IDENTIFIER = "2.5.29.35";
53
    const OID_POLICY_CONSTRAINTS = "2.5.29.36";
54
    const OID_EXT_KEY_USAGE = "2.5.29.37";
55
    const OID_AUTHORITY_ATTRIBUTE_IDENTIFIER = "2.5.29.38";
56
    const OID_ROLE_SPEC_CERT_IDENTIFIER = "2.5.29.39";
57
    const OID_CRL_STREAM_IDENTIFIER = "2.5.29.40";
58
    const OID_BASIC_ATT_CONSTRAINTS = "2.5.29.41";
59
    const OID_DELEGATED_NAME_CONSTRAINTS = "2.5.29.42";
60
    const OID_TIME_SPECIFICATION = "2.5.29.43";
61
    const OID_CRL_SCOPE = "2.5.29.44";
62
    const OID_STATUS_REFERRALS = "2.5.29.45";
63
    const OID_FRESHEST_CRL = "2.5.29.46";
64
    const OID_ORDERED_LIST = "2.5.29.47";
65
    const OID_ATTRIBUTE_DESCRIPTOR = "2.5.29.48";
66
    const OID_USER_NOTICE = "2.5.29.49";
67
    const OID_SOA_IDENTIFIER = "2.5.29.50";
68
    const OID_BASE_UPDATE_TIME = "2.5.29.51";
69
    const OID_ACCEPTABLE_CERT_POLICIES = "2.5.29.52";
70
    const OID_DELTA_INFO = "2.5.29.53";
71
    const OID_INHIBIT_ANY_POLICY = "2.5.29.54";
72
    const OID_TARGET_INFORMATION = "2.5.29.55";
73
    const OID_NO_REV_AVAIL = "2.5.29.56";
74
    const OID_ACCEPTABLE_PRIVILEGE_POLICIES = "2.5.29.57";
75
    const OID_TO_BE_REVOKED = "2.5.29.58";
76
    const OID_REVOKED_GROUPS = "2.5.29.59";
77
    const OID_EXPIRED_CERTS_ON_CRL = "2.5.29.60";
78
    const OID_INDIRECT_ISSUER = "2.5.29.61";
79
    const OID_NO_ASSERTION = "2.5.29.62";
80
    const OID_AA_ISSUING_DISTRIBUTION_POINT = "2.5.29.63";
81
    const OID_ISSUED_ON_BEHALF_OF = "2.5.29.64";
82
    const OID_SINGLE_USE = "2.5.29.65";
83
    const OID_GROUP_AC = "2.5.29.66";
84
    const OID_ALLOWED_ATT_ASS = "2.5.29.67";
85
    const OID_ATTRIBUTE_MAPPINGS = "2.5.29.68";
86
    const OID_HOLDER_NAME_CONSTRAINTS = "2.5.29.69";
87
    
88
    // OID's from private certificate extensions arc
89
    const OID_AUTHORITY_INFORMATION_ACCESS = "1.3.6.1.5.5.7.1.1";
90
    const OID_AA_CONTROLS = "1.3.6.1.5.5.7.1.6";
91
    const OID_SUBJECT_INFORMATION_ACCESS = "1.3.6.1.5.5.7.1.11";
92
    const OID_LOGOTYPE = "1.3.6.1.5.5.7.1.12";
93
    
94
    /**
95
     * Mapping from extension ID to implementation class name.
96
     *
97
     * @internal
98
     *
99
     * @var array
100
     */
101
    const MAP_OID_TO_CLASS = array(
102
        /* @formatter:off */
103
        self::OID_AUTHORITY_KEY_IDENTIFIER => AuthorityKeyIdentifierExtension::class,
104
        self::OID_SUBJECT_KEY_IDENTIFIER => SubjectKeyIdentifierExtension::class,
105
        self::OID_KEY_USAGE => KeyUsageExtension::class,
106
        self::OID_CERTIFICATE_POLICIES => CertificatePoliciesExtension::class,
107
        self::OID_POLICY_MAPPINGS => PolicyMappingsExtension::class,
108
        self::OID_SUBJECT_ALT_NAME => SubjectAlternativeNameExtension::class,
109
        self::OID_ISSUER_ALT_NAME => IssuerAlternativeNameExtension::class,
110
        self::OID_SUBJECT_DIRECTORY_ATTRIBUTES => SubjectDirectoryAttributesExtension::class,
111
        self::OID_BASIC_CONSTRAINTS => BasicConstraintsExtension::class,
112
        self::OID_NAME_CONSTRAINTS => NameConstraintsExtension::class,
113
        self::OID_POLICY_CONSTRAINTS => PolicyConstraintsExtension::class,
114
        self::OID_EXT_KEY_USAGE => ExtendedKeyUsageExtension::class,
115
        self::OID_CRL_DISTRIBUTION_POINTS => CRLDistributionPointsExtension::class,
116
        self::OID_INHIBIT_ANY_POLICY => InhibitAnyPolicyExtension::class,
117
        self::OID_FRESHEST_CRL => FreshestCRLExtension::class,
118
        self::OID_NO_REV_AVAIL => NoRevocationAvailableExtension::class,
119
        self::OID_TARGET_INFORMATION => TargetInformationExtension::class,
120
        self::OID_AUTHORITY_INFORMATION_ACCESS => AuthorityInformationAccessExtension::class,
121
        self::OID_AA_CONTROLS => AAControlsExtension::class,
122
        self::OID_SUBJECT_INFORMATION_ACCESS => SubjectInformationAccessExtension::class
123
        /* @formatter:on */
124
    );
125
    
126
    /**
127
     * Mapping from extensions ID to short name.
128
     *
129
     * @internal
130
     *
131
     * @var array
132
     */
133
    const MAP_OID_TO_NAME = array(
134
        /* @formatter:off */
135
        self::OID_AUTHORITY_KEY_IDENTIFIER => "authorityKeyIdentifier",
136
        self::OID_SUBJECT_KEY_IDENTIFIER => "subjectKeyIdentifier",
137
        self::OID_KEY_USAGE => "keyUsage",
138
        self::OID_PRIVATE_KEY_USAGE_PERIOD => "privateKeyUsagePeriod",
139
        self::OID_CERTIFICATE_POLICIES => "certificatePolicies",
140
        self::OID_POLICY_MAPPINGS => "policyMappings",
141
        self::OID_SUBJECT_ALT_NAME => "subjectAltName",
142
        self::OID_ISSUER_ALT_NAME => "issuerAltName",
143
        self::OID_SUBJECT_DIRECTORY_ATTRIBUTES => "subjectDirectoryAttributes",
144
        self::OID_BASIC_CONSTRAINTS => "basicConstraints",
145
        self::OID_NAME_CONSTRAINTS => "nameConstraints",
146
        self::OID_POLICY_CONSTRAINTS => "policyConstraints",
147
        self::OID_EXT_KEY_USAGE => "extKeyUsage",
148
        self::OID_CRL_DISTRIBUTION_POINTS => "cRLDistributionPoints",
149
        self::OID_INHIBIT_ANY_POLICY => "inhibitAnyPolicy",
150
        self::OID_FRESHEST_CRL => "freshestCRL",
151
        self::OID_NO_REV_AVAIL => "noRevAvail",
152
        self::OID_TARGET_INFORMATION => "targetInformation",
153
        self::OID_AUTHORITY_INFORMATION_ACCESS => "authorityInfoAccess",
154
        self::OID_AA_CONTROLS => "aaControls",
155
        self::OID_SUBJECT_INFORMATION_ACCESS => "subjectInfoAccess",
156
        self::OID_LOGOTYPE => "logotype"
157
        /* @formatter:on */
158
    );
159
    
160
    /**
161
     * Extension's OID.
162
     *
163
     * @var string $_oid
164
     */
165
    protected $_oid;
166
    
167
    /**
168
     * Whether extension is critical.
169
     *
170
     * @var bool $_critical
171
     */
172
    protected $_critical;
173
    
174
    /**
175
     * Get ASN.1 structure of the extension value.
176
     *
177
     * @return Element
178
     */
179
    abstract protected function _valueASN1();
180
    
181
    /**
182
     * Parse extension value from DER.
183
     *
184
     * @param string $data DER data
185
     * @param bool $critical Whether extension is critical
186
     * @throws \BadMethodCallException
187
     * @return self
188
     */
189 1
    protected static function _fromDER(string $data, bool $critical)
190
    {
191 1
        throw new \BadMethodCallException(
192 1
            __FUNCTION__ . " must be implemented in derived class.");
193
    }
194
    
195
    /**
196
     * Constructor.
197
     *
198
     * @param string $oid Extension OID
199
     * @param bool $critical Whether extension is critical
200
     */
201 98
    public function __construct(string $oid, bool $critical)
202
    {
203 98
        $this->_oid = $oid;
204 98
        $this->_critical = $critical;
205 98
    }
206
    
207
    /**
208
     * Initialize from ASN.1.
209
     *
210
     * @param Sequence $seq
211
     * @return self
212
     */
213 51
    public static function fromASN1(Sequence $seq): Extension
214
    {
215 51
        $extnID = $seq->at(0)
216 51
            ->asObjectIdentifier()
217 51
            ->oid();
218 51
        $critical = false;
219 51
        $idx = 1;
220 51
        if ($seq->has($idx, Element::TYPE_BOOLEAN)) {
221 22
            $critical = $seq->at($idx++)
222 22
                ->asBoolean()
223 22
                ->value();
224
        }
225 51
        $data = $seq->at($idx)
226 51
            ->asOctetString()
227 51
            ->string();
228 51
        if (array_key_exists($extnID, self::MAP_OID_TO_CLASS)) {
229 50
            $cls = self::MAP_OID_TO_CLASS[$extnID];
230 50
            return $cls::_fromDER($data, $critical);
231
        }
232 1
        return UnknownExtension::fromRawString($extnID, $critical, $data);
233
    }
234
    
235
    /**
236
     * Get extension OID.
237
     *
238
     * @return string
239
     */
240 66
    public function oid(): string
241
    {
242 66
        return $this->_oid;
243
    }
244
    
245
    /**
246
     * Check whether extension is critical.
247
     *
248
     * @return bool
249
     */
250 20
    public function isCritical(): bool
251
    {
252 20
        return $this->_critical;
253
    }
254
    
255
    /**
256
     * Generate ASN.1 structure.
257
     *
258
     * @return Sequence
259
     */
260 88
    public function toASN1(): Sequence
261
    {
262 88
        $elements = array(new ObjectIdentifier($this->_oid));
263 88
        if ($this->_critical) {
264 58
            $elements[] = new Boolean(true);
265
        }
266 88
        $elements[] = $this->_extnValue();
267 83
        return new Sequence(...$elements);
268
    }
269
    
270
    /**
271
     * Get the extnValue element.
272
     *
273
     * @return OctetString
274
     */
275 86
    protected function _extnValue(): OctetString
276
    {
277 86
        return new OctetString($this->_valueASN1()->toDER());
278
    }
279
    
280
    /**
281
     * Get short name of the extension.
282
     *
283
     * @return string
284
     */
285 3
    public function extensionName(): string
286
    {
287 3
        if (array_key_exists($this->_oid, self::MAP_OID_TO_NAME)) {
288 2
            return self::MAP_OID_TO_NAME[$this->_oid];
289
        }
290 1
        return $this->oid();
291
    }
292
    
293
    /**
294
     *
295
     * @return string
296
     */
297 1
    public function __toString(): string
298
    {
299 1
        return $this->extensionName();
300
    }
301
}
302