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.
Completed
Push — master ( 2569ae...192447 )
by Joni
08:37
created

Extension::extensionName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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