ExtendedKeyUsageExtension   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 4
dl 0
loc 131
ccs 27
cts 27
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A _fromDER() 0 8 1
A has() 0 9 3
A purposes() 0 4 1
A _valueASN1() 0 8 1
A count() 0 4 1
A getIterator() 0 4 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace X509\Certificate\Extension;
6
7
use ASN1\Type\UnspecifiedType;
8
use ASN1\Type\Constructed\Sequence;
9
use ASN1\Type\Primitive\ObjectIdentifier;
10
11
/**
12
 * Implements 'Extended Key Usage' certificate extension.
13
 *
14
 * @link https://tools.ietf.org/html/rfc5280#section-4.2.1.12
15
 */
16
class ExtendedKeyUsageExtension extends Extension implements 
17
    \Countable,
18
    \IteratorAggregate
19
{
20
    const OID_SERVER_AUTH = "1.3.6.1.5.5.7.3.1";
21
    const OID_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2";
22
    const OID_CODE_SIGNING = "1.3.6.1.5.5.7.3.3";
23
    const OID_EMAIL_PROTECTION = "1.3.6.1.5.5.7.3.4";
24
    const OID_IPSEC_END_SYSTEM = "1.3.6.1.5.5.7.3.5";
25
    const OID_IPSEC_TUNNEL = "1.3.6.1.5.5.7.3.6";
26
    const OID_IPSEC_USER = "1.3.6.1.5.5.7.3.7";
27
    const OID_TIME_STAMPING = "1.3.6.1.5.5.7.3.8";
28
    const OID_OCSP_SIGNING = "1.3.6.1.5.5.7.3.9";
29
    const OID_DVCS = "1.3.6.1.5.5.7.3.10";
30
    const OID_SBGP_CERT_AA_SERVER_AUTH = "1.3.6.1.5.5.7.3.11";
31
    const OID_SCVP_RESPONDER = "1.3.6.1.5.5.7.3.12";
32
    const OID_EAP_OVER_PPP = "1.3.6.1.5.5.7.3.13";
33
    const OID_EAP_OVER_LAN = "1.3.6.1.5.5.7.3.14";
34
    const OID_SCVP_SERVER = "1.3.6.1.5.5.7.3.15";
35
    const OID_SCVP_CLIENT = "1.3.6.1.5.5.7.3.16";
36
    const OID_IPSEC_IKE = "1.3.6.1.5.5.7.3.17";
37
    const OID_CAPWAP_AC = "1.3.6.1.5.5.7.3.18";
38
    const OID_CAPWAP_WTP = "1.3.6.1.5.5.7.3.19";
39
    const OID_SIP_DOMAIN = "1.3.6.1.5.5.7.3.20";
40
    const OID_SECURE_SHELL_CLIENT = "1.3.6.1.5.5.7.3.21";
41
    const OID_SECURE_SHELL_SERVER = "1.3.6.1.5.5.7.3.22";
42
    const OID_SEND_ROUTER = "1.3.6.1.5.5.7.3.23";
43
    const OID_SEND_PROXY = "1.3.6.1.5.5.7.3.24";
44
    const OID_SEND_OWNER = "1.3.6.1.5.5.7.3.25";
45
    const OID_SEND_PROXIED_OWNER = "1.3.6.1.5.5.7.3.26";
46
    const OID_CMC_CA = "1.3.6.1.5.5.7.3.27";
47
    const OID_CMC_RA = "1.3.6.1.5.5.7.3.28";
48
    const OID_CMC_ARCHIVE = "1.3.6.1.5.5.7.3.29";
49
    
50
    /**
51
     * Purpose OID's.
52
     *
53
     * @var string[] $_purposes
54
     */
55
    protected $_purposes;
56
    
57
    /**
58
     * Constructor.
59
     *
60
     * @param bool $critical
61
     * @param string ...$purposes
62
     */
63 10
    public function __construct(bool $critical, string ...$purposes)
64
    {
65 10
        parent::__construct(self::OID_EXT_KEY_USAGE, $critical);
66 10
        $this->_purposes = $purposes;
67 10
    }
68
    
69
    /**
70
     *
71
     * {@inheritdoc}
72
     * @return self
73
     */
74 9
    protected static function _fromDER(string $data, bool $critical): self
75
    {
76 9
        $purposes = array_map(
77 9
            function (UnspecifiedType $el) {
78 9
                return $el->asObjectIdentifier()->oid();
79 9
            }, UnspecifiedType::fromDER($data)->asSequence()->elements());
80 9
        return new self($critical, ...$purposes);
81
    }
82
    
83
    /**
84
     * Whether purposes are present.
85
     *
86
     * If multiple purposes are checked, all must be present.
87
     *
88
     * @param string ...$oids
89
     * @return bool
90
     */
91 3
    public function has(string ...$oids): bool
92
    {
93 3
        foreach ($oids as $oid) {
94 3
            if (!in_array($oid, $this->_purposes)) {
95 3
                return false;
96
            }
97
        }
98 2
        return true;
99
    }
100
    
101
    /**
102
     * Get key usage purpose OID's.
103
     *
104
     * @return string[]
105
     */
106 1
    public function purposes(): array
107
    {
108 1
        return $this->_purposes;
109
    }
110
    
111
    /**
112
     *
113
     * {@inheritdoc}
114
     * @return Sequence
115
     */
116 15
    protected function _valueASN1(): Sequence
117
    {
118 15
        $elements = array_map(
119 15
            function ($oid) {
120 15
                return new ObjectIdentifier($oid);
121 15
            }, $this->_purposes);
122 15
        return new Sequence(...$elements);
123
    }
124
    
125
    /**
126
     * Get the number of purposes.
127
     *
128
     * @see \Countable::count()
129
     * @return int
130
     */
131 1
    public function count(): int
132
    {
133 1
        return count($this->_purposes);
134
    }
135
    
136
    /**
137
     * Get iterator for usage purposes.
138
     *
139
     * @see \IteratorAggregate::getIterator()
140
     * @return \ArrayIterator
141
     */
142 1
    public function getIterator(): \ArrayIterator
143
    {
144 1
        return new \ArrayIterator($this->_purposes);
145
    }
146
}
147