PolicyMappingsExtension::issuerDomainPolicies()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
nc 1
cc 1
nop 0
crap 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 X509\Certificate\Extension\CertificatePolicy\PolicyInformation;
10
use X509\Certificate\Extension\PolicyMappings\PolicyMapping;
11
12
/**
13
 * Implements 'Policy Mappings' certificate extension.
14
 *
15
 * @link https://tools.ietf.org/html/rfc5280#section-4.2.1.5
16
 */
17
class PolicyMappingsExtension extends Extension implements 
18
    \Countable,
19
    \IteratorAggregate
20
{
21
    /**
22
     * Policy mappings.
23
     *
24
     * @var PolicyMapping[] $_mappings
25
     */
26
    protected $_mappings;
27
    
28
    /**
29
     * Constructor.
30
     *
31
     * @param bool $critical
32
     * @param PolicyMapping ...$mappings One or more PolicyMapping objects
33
     */
34 5
    public function __construct(bool $critical, PolicyMapping ...$mappings)
35
    {
36 5
        parent::__construct(self::OID_POLICY_MAPPINGS, $critical);
37 5
        $this->_mappings = $mappings;
38 5
    }
39
    
40
    /**
41
     *
42
     * {@inheritdoc}
43
     * @return self
44
     */
45 2
    protected static function _fromDER(string $data, bool $critical): self
46
    {
47 2
        $mappings = array_map(
48 2
            function (UnspecifiedType $el) {
49 1
                return PolicyMapping::fromASN1($el->asSequence());
50 2
            }, UnspecifiedType::fromDER($data)->asSequence()->elements());
51 2
        if (!count($mappings)) {
52 1
            throw new \UnexpectedValueException(
53 1
                "PolicyMappings must have at least one mapping.");
54
        }
55 1
        return new self($critical, ...$mappings);
56
    }
57
    
58
    /**
59
     *
60
     * {@inheritdoc}
61
     * @return Sequence
62
     */
63 6
    protected function _valueASN1(): Sequence
64
    {
65 6
        if (!count($this->_mappings)) {
66 1
            throw new \LogicException("No mappings.");
67
        }
68 5
        $elements = array_map(
69 5
            function (PolicyMapping $mapping) {
70 5
                return $mapping->toASN1();
71 5
            }, $this->_mappings);
72 5
        return new Sequence(...$elements);
73
    }
74
    
75
    /**
76
     * Get all mappings.
77
     *
78
     * @return PolicyMapping[]
79
     */
80 2
    public function mappings(): array
81
    {
82 2
        return $this->_mappings;
83
    }
84
    
85
    /**
86
     * Get mappings flattened into a single array of arrays of subject domains
87
     * keyed by issuer domain.
88
     *
89
     * Eg. if policy mappings contains multiple mappings with the same issuer
90
     * domain policy, their corresponding subject domain policies are placed
91
     * under the same key.
92
     *
93
     * @return (string[])[]
94
     */
95 2
    public function flattenedMappings(): array
96
    {
97 2
        $mappings = array();
98 2
        foreach ($this->_mappings as $mapping) {
99 2
            $idp = $mapping->issuerDomainPolicy();
100 2
            if (!isset($mappings[$idp])) {
101 2
                $mappings[$idp] = array();
102
            }
103 2
            array_push($mappings[$idp], $mapping->subjectDomainPolicy());
104
        }
105 2
        return $mappings;
106
    }
107
    
108
    /**
109
     * Get all subject domain policy OIDs that are mapped to given issuer
110
     * domain policy OID.
111
     *
112
     * @param string $oid Issuer domain policy
113
     * @return string[] List of OIDs in dotted format
114
     */
115 1
    public function issuerMappings(string $oid): array
116
    {
117 1
        $oids = array();
118 1
        foreach ($this->_mappings as $mapping) {
119 1
            if ($mapping->issuerDomainPolicy() == $oid) {
120 1
                $oids[] = $mapping->subjectDomainPolicy();
121
            }
122
        }
123 1
        return $oids;
124
    }
125
    
126
    /**
127
     * Get all mapped issuer domain policy OIDs.
128
     *
129
     * @return string[]
130
     */
131 1
    public function issuerDomainPolicies(): array
132
    {
133 1
        $idps = array_map(
134 1
            function (PolicyMapping $mapping) {
135 1
                return $mapping->issuerDomainPolicy();
136 1
            }, $this->_mappings);
137 1
        return array_values(array_unique($idps));
138
    }
139
    
140
    /**
141
     * Check whether policy mappings have anyPolicy mapped.
142
     *
143
     * RFC 5280 section 4.2.1.5 states that "Policies MUST NOT be mapped either
144
     * to or from the special value anyPolicy".
145
     *
146
     * @return bool
147
     */
148 7
    public function hasAnyPolicyMapping(): bool
149
    {
150 7
        foreach ($this->_mappings as $mapping) {
151 7
            if ($mapping->issuerDomainPolicy() ==
152 7
                 PolicyInformation::OID_ANY_POLICY) {
153 1
                return true;
154
            }
155 6
            if ($mapping->subjectDomainPolicy() ==
156 6
                 PolicyInformation::OID_ANY_POLICY) {
157 6
                return true;
158
            }
159
        }
160 4
        return false;
161
    }
162
    
163
    /**
164
     * Get the number of mappings.
165
     *
166
     * @see \Countable::count()
167
     * @return int
168
     */
169 1
    public function count(): int
170
    {
171 1
        return count($this->_mappings);
172
    }
173
    
174
    /**
175
     * Get iterator for policy mappings.
176
     *
177
     * @see \IteratorAggregate::getIterator()
178
     * @return \ArrayIterator
179
     */
180 1
    public function getIterator(): \ArrayIterator
181
    {
182 1
        return new \ArrayIterator($this->_mappings);
183
    }
184
}
185