Completed
Push — php72 ( 46ea07...aa1b7c )
by Joni
03:36
created
lib/X501/ASN1/RDN.php 2 patches
Indentation   +158 added lines, -158 removed lines patch added patch discarded remove patch
@@ -15,173 +15,173 @@
 block discarded – undo
15 15
  */
16 16
 class RDN implements \Countable, \IteratorAggregate
17 17
 {
18
-    /**
19
-     * Attributes.
20
-     *
21
-     * @var AttributeTypeAndValue[]
22
-     */
23
-    protected $_attribs;
18
+	/**
19
+	 * Attributes.
20
+	 *
21
+	 * @var AttributeTypeAndValue[]
22
+	 */
23
+	protected $_attribs;
24 24
 
25
-    /**
26
-     * Constructor.
27
-     *
28
-     * @param AttributeTypeAndValue ...$attribs One or more attributes
29
-     */
30
-    public function __construct(AttributeTypeAndValue ...$attribs)
31
-    {
32
-        if (!count($attribs)) {
33
-            throw new \UnexpectedValueException(
34
-                'RDN must have at least one AttributeTypeAndValue.');
35
-        }
36
-        $this->_attribs = $attribs;
37
-    }
25
+	/**
26
+	 * Constructor.
27
+	 *
28
+	 * @param AttributeTypeAndValue ...$attribs One or more attributes
29
+	 */
30
+	public function __construct(AttributeTypeAndValue ...$attribs)
31
+	{
32
+		if (!count($attribs)) {
33
+			throw new \UnexpectedValueException(
34
+				'RDN must have at least one AttributeTypeAndValue.');
35
+		}
36
+		$this->_attribs = $attribs;
37
+	}
38 38
 
39
-    /**
40
-     * @return string
41
-     */
42
-    public function __toString()
43
-    {
44
-        return $this->toString();
45
-    }
39
+	/**
40
+	 * @return string
41
+	 */
42
+	public function __toString()
43
+	{
44
+		return $this->toString();
45
+	}
46 46
 
47
-    /**
48
-     * Convenience method to initialize RDN from AttributeValue objects.
49
-     *
50
-     * @param AttributeValue ...$values One or more attributes
51
-     *
52
-     * @return self
53
-     */
54
-    public static function fromAttributeValues(AttributeValue ...$values): self
55
-    {
56
-        $attribs = array_map(
57
-            function (AttributeValue $value) {
58
-                return new AttributeTypeAndValue(
59
-                    new AttributeType($value->oid()), $value);
60
-            }, $values);
61
-        return new self(...$attribs);
62
-    }
47
+	/**
48
+	 * Convenience method to initialize RDN from AttributeValue objects.
49
+	 *
50
+	 * @param AttributeValue ...$values One or more attributes
51
+	 *
52
+	 * @return self
53
+	 */
54
+	public static function fromAttributeValues(AttributeValue ...$values): self
55
+	{
56
+		$attribs = array_map(
57
+			function (AttributeValue $value) {
58
+				return new AttributeTypeAndValue(
59
+					new AttributeType($value->oid()), $value);
60
+			}, $values);
61
+		return new self(...$attribs);
62
+	}
63 63
 
64
-    /**
65
-     * Initialize from ASN.1.
66
-     *
67
-     * @param Set $set
68
-     *
69
-     * @return self
70
-     */
71
-    public static function fromASN1(Set $set): self
72
-    {
73
-        $attribs = array_map(
74
-            function (UnspecifiedType $el) {
75
-                return AttributeTypeAndValue::fromASN1($el->asSequence());
76
-            }, $set->elements());
77
-        return new self(...$attribs);
78
-    }
64
+	/**
65
+	 * Initialize from ASN.1.
66
+	 *
67
+	 * @param Set $set
68
+	 *
69
+	 * @return self
70
+	 */
71
+	public static function fromASN1(Set $set): self
72
+	{
73
+		$attribs = array_map(
74
+			function (UnspecifiedType $el) {
75
+				return AttributeTypeAndValue::fromASN1($el->asSequence());
76
+			}, $set->elements());
77
+		return new self(...$attribs);
78
+	}
79 79
 
80
-    /**
81
-     * Generate ASN.1 structure.
82
-     *
83
-     * @return Set
84
-     */
85
-    public function toASN1(): Set
86
-    {
87
-        $elements = array_map(
88
-            function (AttributeTypeAndValue $tv) {
89
-                return $tv->toASN1();
90
-            }, $this->_attribs);
91
-        $set = new Set(...$elements);
92
-        return $set->sortedSetOf();
93
-    }
80
+	/**
81
+	 * Generate ASN.1 structure.
82
+	 *
83
+	 * @return Set
84
+	 */
85
+	public function toASN1(): Set
86
+	{
87
+		$elements = array_map(
88
+			function (AttributeTypeAndValue $tv) {
89
+				return $tv->toASN1();
90
+			}, $this->_attribs);
91
+		$set = new Set(...$elements);
92
+		return $set->sortedSetOf();
93
+	}
94 94
 
95
-    /**
96
-     * Get name-component string conforming to RFC 2253.
97
-     *
98
-     * @see https://tools.ietf.org/html/rfc2253#section-2.2
99
-     *
100
-     * @return string
101
-     */
102
-    public function toString(): string
103
-    {
104
-        $parts = array_map(
105
-            function (AttributeTypeAndValue $tv) {
106
-                return $tv->toString();
107
-            }, $this->_attribs);
108
-        return implode('+', $parts);
109
-    }
95
+	/**
96
+	 * Get name-component string conforming to RFC 2253.
97
+	 *
98
+	 * @see https://tools.ietf.org/html/rfc2253#section-2.2
99
+	 *
100
+	 * @return string
101
+	 */
102
+	public function toString(): string
103
+	{
104
+		$parts = array_map(
105
+			function (AttributeTypeAndValue $tv) {
106
+				return $tv->toString();
107
+			}, $this->_attribs);
108
+		return implode('+', $parts);
109
+	}
110 110
 
111
-    /**
112
-     * Check whether RDN is semantically equal to other.
113
-     *
114
-     * @param RDN $other Object to compare to
115
-     *
116
-     * @return bool
117
-     */
118
-    public function equals(RDN $other): bool
119
-    {
120
-        // if attribute count doesn't match
121
-        if (count($this) !== count($other)) {
122
-            return false;
123
-        }
124
-        $attribs1 = $this->_attribs;
125
-        $attribs2 = $other->_attribs;
126
-        // if there's multiple attributes, sort using SET OF rules
127
-        if (count($attribs1) > 1) {
128
-            $attribs1 = self::fromASN1($this->toASN1())->_attribs;
129
-            $attribs2 = self::fromASN1($other->toASN1())->_attribs;
130
-        }
131
-        for ($i = count($attribs1) - 1; $i >= 0; --$i) {
132
-            $tv1 = $attribs1[$i];
133
-            $tv2 = $attribs2[$i];
134
-            if (!$tv1->equals($tv2)) {
135
-                return false;
136
-            }
137
-        }
138
-        return true;
139
-    }
111
+	/**
112
+	 * Check whether RDN is semantically equal to other.
113
+	 *
114
+	 * @param RDN $other Object to compare to
115
+	 *
116
+	 * @return bool
117
+	 */
118
+	public function equals(RDN $other): bool
119
+	{
120
+		// if attribute count doesn't match
121
+		if (count($this) !== count($other)) {
122
+			return false;
123
+		}
124
+		$attribs1 = $this->_attribs;
125
+		$attribs2 = $other->_attribs;
126
+		// if there's multiple attributes, sort using SET OF rules
127
+		if (count($attribs1) > 1) {
128
+			$attribs1 = self::fromASN1($this->toASN1())->_attribs;
129
+			$attribs2 = self::fromASN1($other->toASN1())->_attribs;
130
+		}
131
+		for ($i = count($attribs1) - 1; $i >= 0; --$i) {
132
+			$tv1 = $attribs1[$i];
133
+			$tv2 = $attribs2[$i];
134
+			if (!$tv1->equals($tv2)) {
135
+				return false;
136
+			}
137
+		}
138
+		return true;
139
+	}
140 140
 
141
-    /**
142
-     * Get all AttributeTypeAndValue objects.
143
-     *
144
-     * @return AttributeTypeAndValue[]
145
-     */
146
-    public function all(): array
147
-    {
148
-        return $this->_attribs;
149
-    }
141
+	/**
142
+	 * Get all AttributeTypeAndValue objects.
143
+	 *
144
+	 * @return AttributeTypeAndValue[]
145
+	 */
146
+	public function all(): array
147
+	{
148
+		return $this->_attribs;
149
+	}
150 150
 
151
-    /**
152
-     * Get all AttributeTypeAndValue objects of the given attribute type.
153
-     *
154
-     * @param string $name Attribute OID or name
155
-     *
156
-     * @return AttributeTypeAndValue[]
157
-     */
158
-    public function allOf(string $name): array
159
-    {
160
-        $oid = AttributeType::attrNameToOID($name);
161
-        $attribs = array_filter($this->_attribs,
162
-            function (AttributeTypeAndValue $tv) use ($oid) {
163
-                return $tv->oid() === $oid;
164
-            });
165
-        return array_values($attribs);
166
-    }
151
+	/**
152
+	 * Get all AttributeTypeAndValue objects of the given attribute type.
153
+	 *
154
+	 * @param string $name Attribute OID or name
155
+	 *
156
+	 * @return AttributeTypeAndValue[]
157
+	 */
158
+	public function allOf(string $name): array
159
+	{
160
+		$oid = AttributeType::attrNameToOID($name);
161
+		$attribs = array_filter($this->_attribs,
162
+			function (AttributeTypeAndValue $tv) use ($oid) {
163
+				return $tv->oid() === $oid;
164
+			});
165
+		return array_values($attribs);
166
+	}
167 167
 
168
-    /**
169
-     * @see \Countable::count()
170
-     *
171
-     * @return int
172
-     */
173
-    public function count(): int
174
-    {
175
-        return count($this->_attribs);
176
-    }
168
+	/**
169
+	 * @see \Countable::count()
170
+	 *
171
+	 * @return int
172
+	 */
173
+	public function count(): int
174
+	{
175
+		return count($this->_attribs);
176
+	}
177 177
 
178
-    /**
179
-     * @see \IteratorAggregate::getIterator()
180
-     *
181
-     * @return \ArrayIterator
182
-     */
183
-    public function getIterator(): \ArrayIterator
184
-    {
185
-        return new \ArrayIterator($this->_attribs);
186
-    }
178
+	/**
179
+	 * @see \IteratorAggregate::getIterator()
180
+	 *
181
+	 * @return \ArrayIterator
182
+	 */
183
+	public function getIterator(): \ArrayIterator
184
+	{
185
+		return new \ArrayIterator($this->_attribs);
186
+	}
187 187
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X501\ASN1;
6 6
 
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
     public static function fromAttributeValues(AttributeValue ...$values): self
55 55
     {
56 56
         $attribs = array_map(
57
-            function (AttributeValue $value) {
57
+            function(AttributeValue $value) {
58 58
                 return new AttributeTypeAndValue(
59 59
                     new AttributeType($value->oid()), $value);
60 60
             }, $values);
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
     public static function fromASN1(Set $set): self
72 72
     {
73 73
         $attribs = array_map(
74
-            function (UnspecifiedType $el) {
74
+            function(UnspecifiedType $el) {
75 75
                 return AttributeTypeAndValue::fromASN1($el->asSequence());
76 76
             }, $set->elements());
77 77
         return new self(...$attribs);
@@ -85,7 +85,7 @@  discard block
 block discarded – undo
85 85
     public function toASN1(): Set
86 86
     {
87 87
         $elements = array_map(
88
-            function (AttributeTypeAndValue $tv) {
88
+            function(AttributeTypeAndValue $tv) {
89 89
                 return $tv->toASN1();
90 90
             }, $this->_attribs);
91 91
         $set = new Set(...$elements);
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
     public function toString(): string
103 103
     {
104 104
         $parts = array_map(
105
-            function (AttributeTypeAndValue $tv) {
105
+            function(AttributeTypeAndValue $tv) {
106 106
                 return $tv->toString();
107 107
             }, $this->_attribs);
108 108
         return implode('+', $parts);
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
     {
160 160
         $oid = AttributeType::attrNameToOID($name);
161 161
         $attribs = array_filter($this->_attribs,
162
-            function (AttributeTypeAndValue $tv) use ($oid) {
162
+            function(AttributeTypeAndValue $tv) use ($oid) {
163 163
                 return $tv->oid() === $oid;
164 164
             });
165 165
         return array_values($attribs);
Please login to merge, or discard this patch.
lib/X501/ASN1/Name.php 1 patch
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -20,208 +20,208 @@
 block discarded – undo
20 20
  */
21 21
 class Name implements \Countable, \IteratorAggregate
22 22
 {
23
-    /**
24
-     * Relative distinguished name components.
25
-     *
26
-     * @var RDN[]
27
-     */
28
-    protected $_rdns;
29
-
30
-    /**
31
-     * Constructor.
32
-     *
33
-     * @param RDN ...$rdns RDN components
34
-     */
35
-    public function __construct(RDN ...$rdns)
36
-    {
37
-        $this->_rdns = $rdns;
38
-    }
39
-
40
-    /**
41
-     * @return string
42
-     */
43
-    public function __toString()
44
-    {
45
-        return $this->toString();
46
-    }
47
-
48
-    /**
49
-     * Initialize from ASN.1.
50
-     *
51
-     * @param Sequence $seq
52
-     *
53
-     * @return self
54
-     */
55
-    public static function fromASN1(Sequence $seq): self
56
-    {
57
-        $rdns = array_map(
58
-            function (UnspecifiedType $el) {
59
-                return RDN::fromASN1($el->asSet());
60
-            }, $seq->elements());
61
-        return new self(...$rdns);
62
-    }
63
-
64
-    /**
65
-     * Initialize from distinguished name string.
66
-     *
67
-     * @see https://tools.ietf.org/html/rfc1779
68
-     *
69
-     * @param string $str
70
-     *
71
-     * @return self
72
-     */
73
-    public static function fromString(string $str): self
74
-    {
75
-        $rdns = [];
76
-        foreach (DNParser::parseString($str) as $nameComponent) {
77
-            $attribs = [];
78
-            foreach ($nameComponent as [$name, $val]) {
79
-                $type = AttributeType::fromName($name);
80
-                // hexstrings are parsed to ASN.1 elements
81
-                if ($val instanceof Element) {
82
-                    $el = $val;
83
-                } else {
84
-                    $el = AttributeType::asn1StringForType($type->oid(), $val);
85
-                }
86
-                $value = AttributeValue::fromASN1ByOID($type->oid(),
87
-                    $el->asUnspecified());
88
-                $attribs[] = new AttributeTypeAndValue($type, $value);
89
-            }
90
-            $rdns[] = new RDN(...$attribs);
91
-        }
92
-        return new self(...$rdns);
93
-    }
94
-
95
-    /**
96
-     * Generate ASN.1 structure.
97
-     *
98
-     * @return Sequence
99
-     */
100
-    public function toASN1(): Sequence
101
-    {
102
-        $elements = array_map(
103
-            function (RDN $rdn) {
104
-                return $rdn->toASN1();
105
-            }, $this->_rdns);
106
-        return new Sequence(...$elements);
107
-    }
108
-
109
-    /**
110
-     * Get distinguised name string conforming to RFC 2253.
111
-     *
112
-     * @see https://tools.ietf.org/html/rfc2253#section-2.1
113
-     *
114
-     * @return string
115
-     */
116
-    public function toString(): string
117
-    {
118
-        $parts = array_map(
119
-            function (RDN $rdn) {
120
-                return $rdn->toString();
121
-            }, array_reverse($this->_rdns));
122
-        return implode(',', $parts);
123
-    }
124
-
125
-    /**
126
-     * Whether name is semantically equal to other.
127
-     *
128
-     * Comparison conforms to RFC 4518 string preparation algorithm.
129
-     *
130
-     * @see https://tools.ietf.org/html/rfc4518
131
-     *
132
-     * @param Name $other Object to compare to
133
-     *
134
-     * @return bool
135
-     */
136
-    public function equals(Name $other): bool
137
-    {
138
-        // if RDN count doesn't match
139
-        if (count($this) !== count($other)) {
140
-            return false;
141
-        }
142
-        for ($i = count($this) - 1; $i >= 0; --$i) {
143
-            $rdn1 = $this->_rdns[$i];
144
-            $rdn2 = $other->_rdns[$i];
145
-            if (!$rdn1->equals($rdn2)) {
146
-                return false;
147
-            }
148
-        }
149
-        return true;
150
-    }
151
-
152
-    /**
153
-     * Get all RDN objects.
154
-     *
155
-     * @return RDN[]
156
-     */
157
-    public function all(): array
158
-    {
159
-        return $this->_rdns;
160
-    }
161
-
162
-    /**
163
-     * Get the first AttributeValue of given type.
164
-     *
165
-     * Relative name components shall be traversed in encoding order, which is
166
-     * reversed in regards to the string representation.
167
-     * Multi-valued RDN with multiple attributes of the requested type is
168
-     * ambiguous and shall throw an exception.
169
-     *
170
-     * @param string $name Attribute OID or name
171
-     *
172
-     * @throws \RuntimeException If attribute cannot be resolved
173
-     *
174
-     * @return AttributeValue
175
-     */
176
-    public function firstValueOf(string $name): AttributeValue
177
-    {
178
-        $oid = AttributeType::attrNameToOID($name);
179
-        foreach ($this->_rdns as $rdn) {
180
-            $tvs = $rdn->allOf($oid);
181
-            if (count($tvs) > 1) {
182
-                throw new \RangeException("RDN with multiple {$name} attributes.");
183
-            }
184
-            if (1 === count($tvs)) {
185
-                return $tvs[0]->value();
186
-            }
187
-        }
188
-        throw new \RangeException("Attribute {$name} not found.");
189
-    }
190
-
191
-    /**
192
-     * @see \Countable::count()
193
-     *
194
-     * @return int
195
-     */
196
-    public function count(): int
197
-    {
198
-        return count($this->_rdns);
199
-    }
200
-
201
-    /**
202
-     * Get the number of attributes of given type.
203
-     *
204
-     * @param string $name Attribute OID or name
205
-     *
206
-     * @return int
207
-     */
208
-    public function countOfType(string $name): int
209
-    {
210
-        $oid = AttributeType::attrNameToOID($name);
211
-        return (int) array_sum(
212
-            array_map(
213
-                function (RDN $rdn) use ($oid): int {
214
-                    return count($rdn->allOf($oid));
215
-                }, $this->_rdns));
216
-    }
217
-
218
-    /**
219
-     * @see \IteratorAggregate::getIterator()
220
-     *
221
-     * @return \ArrayIterator
222
-     */
223
-    public function getIterator(): \ArrayIterator
224
-    {
225
-        return new \ArrayIterator($this->_rdns);
226
-    }
23
+	/**
24
+	 * Relative distinguished name components.
25
+	 *
26
+	 * @var RDN[]
27
+	 */
28
+	protected $_rdns;
29
+
30
+	/**
31
+	 * Constructor.
32
+	 *
33
+	 * @param RDN ...$rdns RDN components
34
+	 */
35
+	public function __construct(RDN ...$rdns)
36
+	{
37
+		$this->_rdns = $rdns;
38
+	}
39
+
40
+	/**
41
+	 * @return string
42
+	 */
43
+	public function __toString()
44
+	{
45
+		return $this->toString();
46
+	}
47
+
48
+	/**
49
+	 * Initialize from ASN.1.
50
+	 *
51
+	 * @param Sequence $seq
52
+	 *
53
+	 * @return self
54
+	 */
55
+	public static function fromASN1(Sequence $seq): self
56
+	{
57
+		$rdns = array_map(
58
+			function (UnspecifiedType $el) {
59
+				return RDN::fromASN1($el->asSet());
60
+			}, $seq->elements());
61
+		return new self(...$rdns);
62
+	}
63
+
64
+	/**
65
+	 * Initialize from distinguished name string.
66
+	 *
67
+	 * @see https://tools.ietf.org/html/rfc1779
68
+	 *
69
+	 * @param string $str
70
+	 *
71
+	 * @return self
72
+	 */
73
+	public static function fromString(string $str): self
74
+	{
75
+		$rdns = [];
76
+		foreach (DNParser::parseString($str) as $nameComponent) {
77
+			$attribs = [];
78
+			foreach ($nameComponent as [$name, $val]) {
79
+				$type = AttributeType::fromName($name);
80
+				// hexstrings are parsed to ASN.1 elements
81
+				if ($val instanceof Element) {
82
+					$el = $val;
83
+				} else {
84
+					$el = AttributeType::asn1StringForType($type->oid(), $val);
85
+				}
86
+				$value = AttributeValue::fromASN1ByOID($type->oid(),
87
+					$el->asUnspecified());
88
+				$attribs[] = new AttributeTypeAndValue($type, $value);
89
+			}
90
+			$rdns[] = new RDN(...$attribs);
91
+		}
92
+		return new self(...$rdns);
93
+	}
94
+
95
+	/**
96
+	 * Generate ASN.1 structure.
97
+	 *
98
+	 * @return Sequence
99
+	 */
100
+	public function toASN1(): Sequence
101
+	{
102
+		$elements = array_map(
103
+			function (RDN $rdn) {
104
+				return $rdn->toASN1();
105
+			}, $this->_rdns);
106
+		return new Sequence(...$elements);
107
+	}
108
+
109
+	/**
110
+	 * Get distinguised name string conforming to RFC 2253.
111
+	 *
112
+	 * @see https://tools.ietf.org/html/rfc2253#section-2.1
113
+	 *
114
+	 * @return string
115
+	 */
116
+	public function toString(): string
117
+	{
118
+		$parts = array_map(
119
+			function (RDN $rdn) {
120
+				return $rdn->toString();
121
+			}, array_reverse($this->_rdns));
122
+		return implode(',', $parts);
123
+	}
124
+
125
+	/**
126
+	 * Whether name is semantically equal to other.
127
+	 *
128
+	 * Comparison conforms to RFC 4518 string preparation algorithm.
129
+	 *
130
+	 * @see https://tools.ietf.org/html/rfc4518
131
+	 *
132
+	 * @param Name $other Object to compare to
133
+	 *
134
+	 * @return bool
135
+	 */
136
+	public function equals(Name $other): bool
137
+	{
138
+		// if RDN count doesn't match
139
+		if (count($this) !== count($other)) {
140
+			return false;
141
+		}
142
+		for ($i = count($this) - 1; $i >= 0; --$i) {
143
+			$rdn1 = $this->_rdns[$i];
144
+			$rdn2 = $other->_rdns[$i];
145
+			if (!$rdn1->equals($rdn2)) {
146
+				return false;
147
+			}
148
+		}
149
+		return true;
150
+	}
151
+
152
+	/**
153
+	 * Get all RDN objects.
154
+	 *
155
+	 * @return RDN[]
156
+	 */
157
+	public function all(): array
158
+	{
159
+		return $this->_rdns;
160
+	}
161
+
162
+	/**
163
+	 * Get the first AttributeValue of given type.
164
+	 *
165
+	 * Relative name components shall be traversed in encoding order, which is
166
+	 * reversed in regards to the string representation.
167
+	 * Multi-valued RDN with multiple attributes of the requested type is
168
+	 * ambiguous and shall throw an exception.
169
+	 *
170
+	 * @param string $name Attribute OID or name
171
+	 *
172
+	 * @throws \RuntimeException If attribute cannot be resolved
173
+	 *
174
+	 * @return AttributeValue
175
+	 */
176
+	public function firstValueOf(string $name): AttributeValue
177
+	{
178
+		$oid = AttributeType::attrNameToOID($name);
179
+		foreach ($this->_rdns as $rdn) {
180
+			$tvs = $rdn->allOf($oid);
181
+			if (count($tvs) > 1) {
182
+				throw new \RangeException("RDN with multiple {$name} attributes.");
183
+			}
184
+			if (1 === count($tvs)) {
185
+				return $tvs[0]->value();
186
+			}
187
+		}
188
+		throw new \RangeException("Attribute {$name} not found.");
189
+	}
190
+
191
+	/**
192
+	 * @see \Countable::count()
193
+	 *
194
+	 * @return int
195
+	 */
196
+	public function count(): int
197
+	{
198
+		return count($this->_rdns);
199
+	}
200
+
201
+	/**
202
+	 * Get the number of attributes of given type.
203
+	 *
204
+	 * @param string $name Attribute OID or name
205
+	 *
206
+	 * @return int
207
+	 */
208
+	public function countOfType(string $name): int
209
+	{
210
+		$oid = AttributeType::attrNameToOID($name);
211
+		return (int) array_sum(
212
+			array_map(
213
+				function (RDN $rdn) use ($oid): int {
214
+					return count($rdn->allOf($oid));
215
+				}, $this->_rdns));
216
+	}
217
+
218
+	/**
219
+	 * @see \IteratorAggregate::getIterator()
220
+	 *
221
+	 * @return \ArrayIterator
222
+	 */
223
+	public function getIterator(): \ArrayIterator
224
+	{
225
+		return new \ArrayIterator($this->_rdns);
226
+	}
227 227
 }
Please login to merge, or discard this patch.
lib/X501/ASN1/AttributeType.php 1 patch
Indentation   +424 added lines, -424 removed lines patch added patch discarded remove patch
@@ -17,441 +17,441 @@
 block discarded – undo
17 17
  */
18 18
 class AttributeType
19 19
 {
20
-    // OID's from 2.5.4 arc
21
-    const OID_OBJECT_CLASS = '2.5.4.0';
22
-    const OID_ALIASED_ENTRY_NAME = '2.5.4.1';
23
-    const OID_KNOWLEDGE_INFORMATION = '2.5.4.2';
24
-    const OID_COMMON_NAME = '2.5.4.3';
25
-    const OID_SURNAME = '2.5.4.4';
26
-    const OID_SERIAL_NUMBER = '2.5.4.5';
27
-    const OID_COUNTRY_NAME = '2.5.4.6';
28
-    const OID_LOCALITY_NAME = '2.5.4.7';
29
-    const OID_STATE_OR_PROVINCE_NAME = '2.5.4.8';
30
-    const OID_STREET_ADDRESS = '2.5.4.9';
31
-    const OID_ORGANIZATION_NAME = '2.5.4.10';
32
-    const OID_ORGANIZATIONAL_UNIT_NAME = '2.5.4.11';
33
-    const OID_TITLE = '2.5.4.12';
34
-    const OID_DESCRIPTION = '2.5.4.13';
35
-    const OID_SEARCH_GUIDE = '2.5.4.14';
36
-    const OID_BUSINESS_CATEGORY = '2.5.4.15';
37
-    const OID_POSTAL_ADDRESS = '2.5.4.16';
38
-    const OID_POSTAL_CODE = '2.5.4.17';
39
-    const OID_POST_OFFICE_BOX = '2.5.4.18';
40
-    const OID_PHYSICAL_DELIVERY_OFFICE_NAME = '2.5.4.19';
41
-    const OID_TELEPHONE_NUMBER = '2.5.4.20';
42
-    const OID_TELEX_NUMBER = '2.5.4.21';
43
-    const OID_TELETEX_TERMINAL_IDENTIFIER = '2.5.4.22';
44
-    const OID_FACSIMILE_TELEPHONE_NUMBER = '2.5.4.23';
45
-    const OID_X121_ADDRESS = '2.5.4.24';
46
-    const OID_INTERNATIONAL_ISDN_NUMBER = '2.5.4.25';
47
-    const OID_REGISTERED_ADDRESS = '2.5.4.26';
48
-    const OID_DESTINATION_INDICATOR = '2.5.4.27';
49
-    const OID_PREFERRED_DELIVERY_METHOD = '2.5.4.28';
50
-    const OID_PRESENTATION_ADDRESS = '2.5.4.29';
51
-    const OID_SUPPORTED_APPLICATION_CONTEXT = '2.5.4.30';
52
-    const OID_MEMBER = '2.5.4.31';
53
-    const OID_OWNER = '2.5.4.32';
54
-    const OID_ROLE_OCCUPANT = '2.5.4.33';
55
-    const OID_SEE_ALSO = '2.5.4.34';
56
-    const OID_USER_PASSWORD = '2.5.4.35';
57
-    const OID_USER_CERTIFICATE = '2.5.4.36';
58
-    const OID_CA_CERTIFICATE = '2.5.4.37';
59
-    const OID_AUTHORITY_REVOCATION_LIST = '2.5.4.38';
60
-    const OID_CERTIFICATE_REVOCATION_LIST = '2.5.4.39';
61
-    const OID_CROSS_CERTIFICATE_PAIR = '2.5.4.40';
62
-    const OID_NAME = '2.5.4.41';
63
-    const OID_GIVEN_NAME = '2.5.4.42';
64
-    const OID_INITIALS = '2.5.4.43';
65
-    const OID_GENERATION_QUALIFIER = '2.5.4.44';
66
-    const OID_UNIQUE_IDENTIFIER = '2.5.4.45';
67
-    const OID_DN_QUALIFIER = '2.5.4.46';
68
-    const OID_ENHANCED_SEARCH_GUIDE = '2.5.4.47';
69
-    const OID_PROTOCOL_INFORMATION = '2.5.4.48';
70
-    const OID_DISTINGUISHED_NAME = '2.5.4.49';
71
-    const OID_UNIQUE_MEMBER = '2.5.4.50';
72
-    const OID_HOUSE_IDENTIFIER = '2.5.4.51';
73
-    const OID_SUPPORTED_ALGORITHMS = '2.5.4.52';
74
-    const OID_DELTA_REVOCATION_LIST = '2.5.4.53';
75
-    const OID_DMD_NAME = '2.5.4.54';
76
-    const OID_CLEARANCE = '2.5.4.55';
77
-    const OID_DEFAULT_DIR_QOP = '2.5.4.56';
78
-    const OID_ATTRIBUTE_INTEGRITY_INFO = '2.5.4.57';
79
-    const OID_ATTRIBUTE_CERTIFICATE = '2.5.4.58';
80
-    const OID_ATTRIBUTE_CERTIFICATE_REVOCATION_LIST = '2.5.4.59';
81
-    const OID_CONF_KEY_INFO = '2.5.4.60';
82
-    const OID_AA_CERTIFICATE = '2.5.4.61';
83
-    const OID_ATTRIBUTE_DESCRIPTOR_CERTIFICATE = '2.5.4.62';
84
-    const OID_ATTRIBUTE_AUTHORITY_REVOCATION_LIST = '2.5.4.63';
85
-    const OID_FAMILY_INFORMATION = '2.5.4.64';
86
-    const OID_PSEUDONYM = '2.5.4.65';
87
-    const OID_COMMUNICATIONS_SERVICE = '2.5.4.66';
88
-    const OID_COMMUNICATIONS_NETWORK = '2.5.4.67';
89
-    const OID_CERTIFICATION_PRACTICE_STMT = '2.5.4.68';
90
-    const OID_CERTIFICATE_POLICY = '2.5.4.69';
91
-    const OID_PKI_PATH = '2.5.4.70';
92
-    const OID_PRIV_POLICY = '2.5.4.71';
93
-    const OID_ROLE = '2.5.4.72';
94
-    const OID_DELEGATION_PATH = '2.5.4.73';
95
-    const OID_PROT_PRIV_POLICY = '2.5.4.74';
96
-    const OID_XML_PRIVILEGE_INFO = '2.5.4.75';
97
-    const OID_XML_PRIV_POLICY = '2.5.4.76';
98
-    const OID_UUID_PAIR = '2.5.4.77';
99
-    const OID_TAG_OID = '2.5.4.78';
100
-    const OID_UII_FORMAT = '2.5.4.79';
101
-    const OID_UII_IN_URH = '2.5.4.80';
102
-    const OID_CONTENT_URL = '2.5.4.81';
103
-    const OID_PERMISSION = '2.5.4.82';
104
-    const OID_URI = '2.5.4.83';
105
-    const OID_PWD_ATTRIBUTE = '2.5.4.84';
106
-    const OID_USER_PWD = '2.5.4.85';
107
-    const OID_URN = '2.5.4.86';
108
-    const OID_URL = '2.5.4.87';
109
-    const OID_UTM_COORDINATES = '2.5.4.88';
110
-    const OID_URNC = '2.5.4.89';
111
-    const OID_UII = '2.5.4.90';
112
-    const OID_EPC = '2.5.4.91';
113
-    const OID_TAG_AFI = '2.5.4.92';
114
-    const OID_EPC_FORMAT = '2.5.4.93';
115
-    const OID_EPC_IN_URN = '2.5.4.94';
116
-    const OID_LDAP_URL = '2.5.4.95';
117
-    const OID_TAG_LOCATION = '2.5.4.96';
118
-    const OID_ORGANIZATION_IDENTIFIER = '2.5.4.97';
20
+	// OID's from 2.5.4 arc
21
+	const OID_OBJECT_CLASS = '2.5.4.0';
22
+	const OID_ALIASED_ENTRY_NAME = '2.5.4.1';
23
+	const OID_KNOWLEDGE_INFORMATION = '2.5.4.2';
24
+	const OID_COMMON_NAME = '2.5.4.3';
25
+	const OID_SURNAME = '2.5.4.4';
26
+	const OID_SERIAL_NUMBER = '2.5.4.5';
27
+	const OID_COUNTRY_NAME = '2.5.4.6';
28
+	const OID_LOCALITY_NAME = '2.5.4.7';
29
+	const OID_STATE_OR_PROVINCE_NAME = '2.5.4.8';
30
+	const OID_STREET_ADDRESS = '2.5.4.9';
31
+	const OID_ORGANIZATION_NAME = '2.5.4.10';
32
+	const OID_ORGANIZATIONAL_UNIT_NAME = '2.5.4.11';
33
+	const OID_TITLE = '2.5.4.12';
34
+	const OID_DESCRIPTION = '2.5.4.13';
35
+	const OID_SEARCH_GUIDE = '2.5.4.14';
36
+	const OID_BUSINESS_CATEGORY = '2.5.4.15';
37
+	const OID_POSTAL_ADDRESS = '2.5.4.16';
38
+	const OID_POSTAL_CODE = '2.5.4.17';
39
+	const OID_POST_OFFICE_BOX = '2.5.4.18';
40
+	const OID_PHYSICAL_DELIVERY_OFFICE_NAME = '2.5.4.19';
41
+	const OID_TELEPHONE_NUMBER = '2.5.4.20';
42
+	const OID_TELEX_NUMBER = '2.5.4.21';
43
+	const OID_TELETEX_TERMINAL_IDENTIFIER = '2.5.4.22';
44
+	const OID_FACSIMILE_TELEPHONE_NUMBER = '2.5.4.23';
45
+	const OID_X121_ADDRESS = '2.5.4.24';
46
+	const OID_INTERNATIONAL_ISDN_NUMBER = '2.5.4.25';
47
+	const OID_REGISTERED_ADDRESS = '2.5.4.26';
48
+	const OID_DESTINATION_INDICATOR = '2.5.4.27';
49
+	const OID_PREFERRED_DELIVERY_METHOD = '2.5.4.28';
50
+	const OID_PRESENTATION_ADDRESS = '2.5.4.29';
51
+	const OID_SUPPORTED_APPLICATION_CONTEXT = '2.5.4.30';
52
+	const OID_MEMBER = '2.5.4.31';
53
+	const OID_OWNER = '2.5.4.32';
54
+	const OID_ROLE_OCCUPANT = '2.5.4.33';
55
+	const OID_SEE_ALSO = '2.5.4.34';
56
+	const OID_USER_PASSWORD = '2.5.4.35';
57
+	const OID_USER_CERTIFICATE = '2.5.4.36';
58
+	const OID_CA_CERTIFICATE = '2.5.4.37';
59
+	const OID_AUTHORITY_REVOCATION_LIST = '2.5.4.38';
60
+	const OID_CERTIFICATE_REVOCATION_LIST = '2.5.4.39';
61
+	const OID_CROSS_CERTIFICATE_PAIR = '2.5.4.40';
62
+	const OID_NAME = '2.5.4.41';
63
+	const OID_GIVEN_NAME = '2.5.4.42';
64
+	const OID_INITIALS = '2.5.4.43';
65
+	const OID_GENERATION_QUALIFIER = '2.5.4.44';
66
+	const OID_UNIQUE_IDENTIFIER = '2.5.4.45';
67
+	const OID_DN_QUALIFIER = '2.5.4.46';
68
+	const OID_ENHANCED_SEARCH_GUIDE = '2.5.4.47';
69
+	const OID_PROTOCOL_INFORMATION = '2.5.4.48';
70
+	const OID_DISTINGUISHED_NAME = '2.5.4.49';
71
+	const OID_UNIQUE_MEMBER = '2.5.4.50';
72
+	const OID_HOUSE_IDENTIFIER = '2.5.4.51';
73
+	const OID_SUPPORTED_ALGORITHMS = '2.5.4.52';
74
+	const OID_DELTA_REVOCATION_LIST = '2.5.4.53';
75
+	const OID_DMD_NAME = '2.5.4.54';
76
+	const OID_CLEARANCE = '2.5.4.55';
77
+	const OID_DEFAULT_DIR_QOP = '2.5.4.56';
78
+	const OID_ATTRIBUTE_INTEGRITY_INFO = '2.5.4.57';
79
+	const OID_ATTRIBUTE_CERTIFICATE = '2.5.4.58';
80
+	const OID_ATTRIBUTE_CERTIFICATE_REVOCATION_LIST = '2.5.4.59';
81
+	const OID_CONF_KEY_INFO = '2.5.4.60';
82
+	const OID_AA_CERTIFICATE = '2.5.4.61';
83
+	const OID_ATTRIBUTE_DESCRIPTOR_CERTIFICATE = '2.5.4.62';
84
+	const OID_ATTRIBUTE_AUTHORITY_REVOCATION_LIST = '2.5.4.63';
85
+	const OID_FAMILY_INFORMATION = '2.5.4.64';
86
+	const OID_PSEUDONYM = '2.5.4.65';
87
+	const OID_COMMUNICATIONS_SERVICE = '2.5.4.66';
88
+	const OID_COMMUNICATIONS_NETWORK = '2.5.4.67';
89
+	const OID_CERTIFICATION_PRACTICE_STMT = '2.5.4.68';
90
+	const OID_CERTIFICATE_POLICY = '2.5.4.69';
91
+	const OID_PKI_PATH = '2.5.4.70';
92
+	const OID_PRIV_POLICY = '2.5.4.71';
93
+	const OID_ROLE = '2.5.4.72';
94
+	const OID_DELEGATION_PATH = '2.5.4.73';
95
+	const OID_PROT_PRIV_POLICY = '2.5.4.74';
96
+	const OID_XML_PRIVILEGE_INFO = '2.5.4.75';
97
+	const OID_XML_PRIV_POLICY = '2.5.4.76';
98
+	const OID_UUID_PAIR = '2.5.4.77';
99
+	const OID_TAG_OID = '2.5.4.78';
100
+	const OID_UII_FORMAT = '2.5.4.79';
101
+	const OID_UII_IN_URH = '2.5.4.80';
102
+	const OID_CONTENT_URL = '2.5.4.81';
103
+	const OID_PERMISSION = '2.5.4.82';
104
+	const OID_URI = '2.5.4.83';
105
+	const OID_PWD_ATTRIBUTE = '2.5.4.84';
106
+	const OID_USER_PWD = '2.5.4.85';
107
+	const OID_URN = '2.5.4.86';
108
+	const OID_URL = '2.5.4.87';
109
+	const OID_UTM_COORDINATES = '2.5.4.88';
110
+	const OID_URNC = '2.5.4.89';
111
+	const OID_UII = '2.5.4.90';
112
+	const OID_EPC = '2.5.4.91';
113
+	const OID_TAG_AFI = '2.5.4.92';
114
+	const OID_EPC_FORMAT = '2.5.4.93';
115
+	const OID_EPC_IN_URN = '2.5.4.94';
116
+	const OID_LDAP_URL = '2.5.4.95';
117
+	const OID_TAG_LOCATION = '2.5.4.96';
118
+	const OID_ORGANIZATION_IDENTIFIER = '2.5.4.97';
119 119
 
120
-    // Miscellany attribute OID's
121
-    const OID_CLEARANCE_X501 = '2.5.1.5.55';
120
+	// Miscellany attribute OID's
121
+	const OID_CLEARANCE_X501 = '2.5.1.5.55';
122 122
 
123
-    /**
124
-     * Default ASN.1 string types for attributes.
125
-     *
126
-     * Attributes not mapped here shall use UTF8String as a default type.
127
-     *
128
-     * @internal
129
-     *
130
-     * @var array
131
-     */
132
-    const MAP_ATTR_TO_STR_TYPE = [
133
-        self::OID_DN_QUALIFIER => Element::TYPE_PRINTABLE_STRING,
134
-        self::OID_COUNTRY_NAME => Element::TYPE_PRINTABLE_STRING,
135
-        self::OID_SERIAL_NUMBER => Element::TYPE_PRINTABLE_STRING,
136
-    ];
123
+	/**
124
+	 * Default ASN.1 string types for attributes.
125
+	 *
126
+	 * Attributes not mapped here shall use UTF8String as a default type.
127
+	 *
128
+	 * @internal
129
+	 *
130
+	 * @var array
131
+	 */
132
+	const MAP_ATTR_TO_STR_TYPE = [
133
+		self::OID_DN_QUALIFIER => Element::TYPE_PRINTABLE_STRING,
134
+		self::OID_COUNTRY_NAME => Element::TYPE_PRINTABLE_STRING,
135
+		self::OID_SERIAL_NUMBER => Element::TYPE_PRINTABLE_STRING,
136
+	];
137 137
 
138
-    /**
139
-     * OID to attribute names mapping.
140
-     *
141
-     * First name is the primary name. If there's more than one name, others may
142
-     * be used as an alias.
143
-     *
144
-     * Generated using ldap-attribs.py.
145
-     *
146
-     * @internal
147
-     *
148
-     * @var array
149
-     */
150
-    const MAP_OID_TO_NAME = [
151
-        '0.9.2342.19200300.100.1.1' => ['uid', 'userid'],
152
-        '0.9.2342.19200300.100.1.2' => ['textEncodedORAddress'],
153
-        '0.9.2342.19200300.100.1.3' => ['mail', 'rfc822Mailbox'],
154
-        '0.9.2342.19200300.100.1.4' => ['info'],
155
-        '0.9.2342.19200300.100.1.5' => ['drink', 'favouriteDrink'],
156
-        '0.9.2342.19200300.100.1.6' => ['roomNumber'],
157
-        '0.9.2342.19200300.100.1.7' => ['photo'],
158
-        '0.9.2342.19200300.100.1.8' => ['userClass'],
159
-        '0.9.2342.19200300.100.1.9' => ['host'],
160
-        '0.9.2342.19200300.100.1.10' => ['manager'],
161
-        '0.9.2342.19200300.100.1.11' => ['documentIdentifier'],
162
-        '0.9.2342.19200300.100.1.12' => ['documentTitle'],
163
-        '0.9.2342.19200300.100.1.13' => ['documentVersion'],
164
-        '0.9.2342.19200300.100.1.14' => ['documentAuthor'],
165
-        '0.9.2342.19200300.100.1.15' => ['documentLocation'],
166
-        '0.9.2342.19200300.100.1.20' => ['homePhone', 'homeTelephoneNumber'],
167
-        '0.9.2342.19200300.100.1.21' => ['secretary'],
168
-        '0.9.2342.19200300.100.1.22' => ['otherMailbox'],
169
-        '0.9.2342.19200300.100.1.25' => ['dc', 'domainComponent'],
170
-        '0.9.2342.19200300.100.1.26' => ['aRecord'],
171
-        '0.9.2342.19200300.100.1.27' => ['mDRecord'],
172
-        '0.9.2342.19200300.100.1.28' => ['mXRecord'],
173
-        '0.9.2342.19200300.100.1.29' => ['nSRecord'],
174
-        '0.9.2342.19200300.100.1.30' => ['sOARecord'],
175
-        '0.9.2342.19200300.100.1.31' => ['cNAMERecord'],
176
-        '0.9.2342.19200300.100.1.37' => ['associatedDomain'],
177
-        '0.9.2342.19200300.100.1.38' => ['associatedName'],
178
-        '0.9.2342.19200300.100.1.39' => ['homePostalAddress'],
179
-        '0.9.2342.19200300.100.1.40' => ['personalTitle'],
180
-        '0.9.2342.19200300.100.1.41' => ['mobile', 'mobileTelephoneNumber'],
181
-        '0.9.2342.19200300.100.1.42' => ['pager', 'pagerTelephoneNumber'],
182
-        '0.9.2342.19200300.100.1.43' => ['co', 'friendlyCountryName'],
183
-        '0.9.2342.19200300.100.1.44' => ['uniqueIdentifier'],
184
-        '0.9.2342.19200300.100.1.45' => ['organizationalStatus'],
185
-        '0.9.2342.19200300.100.1.46' => ['janetMailbox'],
186
-        '0.9.2342.19200300.100.1.47' => ['mailPreferenceOption'],
187
-        '0.9.2342.19200300.100.1.48' => ['buildingName'],
188
-        '0.9.2342.19200300.100.1.49' => ['dSAQuality'],
189
-        '0.9.2342.19200300.100.1.50' => ['singleLevelQuality'],
190
-        '0.9.2342.19200300.100.1.51' => ['subtreeMinimumQuality'],
191
-        '0.9.2342.19200300.100.1.52' => ['subtreeMaximumQuality'],
192
-        '0.9.2342.19200300.100.1.53' => ['personalSignature'],
193
-        '0.9.2342.19200300.100.1.54' => ['dITRedirect'],
194
-        '0.9.2342.19200300.100.1.55' => ['audio'],
195
-        '0.9.2342.19200300.100.1.56' => ['documentPublisher'],
196
-        '0.9.2342.19200300.100.1.60' => ['jpegPhoto'],
197
-        '1.2.840.113549.1.9.1' => ['email', 'emailAddress', 'pkcs9email'],
198
-        '1.2.840.113556.1.2.102' => ['memberOf'],
199
-        '1.3.6.1.1.1.1.0' => ['uidNumber'],
200
-        '1.3.6.1.1.1.1.1' => ['gidNumber'],
201
-        '1.3.6.1.1.1.1.2' => ['gecos'],
202
-        '1.3.6.1.1.1.1.3' => ['homeDirectory'],
203
-        '1.3.6.1.1.1.1.4' => ['loginShell'],
204
-        '1.3.6.1.1.1.1.5' => ['shadowLastChange'],
205
-        '1.3.6.1.1.1.1.6' => ['shadowMin'],
206
-        '1.3.6.1.1.1.1.7' => ['shadowMax'],
207
-        '1.3.6.1.1.1.1.8' => ['shadowWarning'],
208
-        '1.3.6.1.1.1.1.9' => ['shadowInactive'],
209
-        '1.3.6.1.1.1.1.10' => ['shadowExpire'],
210
-        '1.3.6.1.1.1.1.11' => ['shadowFlag'],
211
-        '1.3.6.1.1.1.1.12' => ['memberUid'],
212
-        '1.3.6.1.1.1.1.13' => ['memberNisNetgroup'],
213
-        '1.3.6.1.1.1.1.14' => ['nisNetgroupTriple'],
214
-        '1.3.6.1.1.1.1.15' => ['ipServicePort'],
215
-        '1.3.6.1.1.1.1.16' => ['ipServiceProtocol'],
216
-        '1.3.6.1.1.1.1.17' => ['ipProtocolNumber'],
217
-        '1.3.6.1.1.1.1.18' => ['oncRpcNumber'],
218
-        '1.3.6.1.1.1.1.19' => ['ipHostNumber'],
219
-        '1.3.6.1.1.1.1.20' => ['ipNetworkNumber'],
220
-        '1.3.6.1.1.1.1.21' => ['ipNetmaskNumber'],
221
-        '1.3.6.1.1.1.1.22' => ['macAddress'],
222
-        '1.3.6.1.1.1.1.23' => ['bootParameter'],
223
-        '1.3.6.1.1.1.1.24' => ['bootFile'],
224
-        '1.3.6.1.1.1.1.26' => ['nisMapName'],
225
-        '1.3.6.1.1.1.1.27' => ['nisMapEntry'],
226
-        '1.3.6.1.1.4' => ['vendorName'],
227
-        '1.3.6.1.1.5' => ['vendorVersion'],
228
-        '1.3.6.1.1.16.4' => ['entryUUID'],
229
-        '1.3.6.1.1.20' => ['entryDN'],
230
-        '2.5.4.0' => ['objectClass'],
231
-        '2.5.4.1' => ['aliasedObjectName', 'aliasedEntryName'],
232
-        '2.5.4.2' => ['knowledgeInformation'],
233
-        '2.5.4.3' => ['cn', 'commonName'],
234
-        '2.5.4.4' => ['sn', 'surname'],
235
-        '2.5.4.5' => ['serialNumber'],
236
-        '2.5.4.6' => ['c', 'countryName'],
237
-        '2.5.4.7' => ['l', 'localityName'],
238
-        '2.5.4.8' => ['st', 'stateOrProvinceName'],
239
-        '2.5.4.9' => ['street', 'streetAddress'],
240
-        '2.5.4.10' => ['o', 'organizationName'],
241
-        '2.5.4.11' => ['ou', 'organizationalUnitName'],
242
-        '2.5.4.12' => ['title'],
243
-        '2.5.4.13' => ['description'],
244
-        '2.5.4.14' => ['searchGuide'],
245
-        '2.5.4.15' => ['businessCategory'],
246
-        '2.5.4.16' => ['postalAddress'],
247
-        '2.5.4.17' => ['postalCode'],
248
-        '2.5.4.18' => ['postOfficeBox'],
249
-        '2.5.4.19' => ['physicalDeliveryOfficeName'],
250
-        '2.5.4.20' => ['telephoneNumber'],
251
-        '2.5.4.21' => ['telexNumber'],
252
-        '2.5.4.22' => ['teletexTerminalIdentifier'],
253
-        '2.5.4.23' => ['facsimileTelephoneNumber', 'fax'],
254
-        '2.5.4.24' => ['x121Address'],
255
-        '2.5.4.25' => ['internationaliSDNNumber'],
256
-        '2.5.4.26' => ['registeredAddress'],
257
-        '2.5.4.27' => ['destinationIndicator'],
258
-        '2.5.4.28' => ['preferredDeliveryMethod'],
259
-        '2.5.4.29' => ['presentationAddress'],
260
-        '2.5.4.30' => ['supportedApplicationContext'],
261
-        '2.5.4.31' => ['member'],
262
-        '2.5.4.32' => ['owner'],
263
-        '2.5.4.33' => ['roleOccupant'],
264
-        '2.5.4.34' => ['seeAlso'],
265
-        '2.5.4.35' => ['userPassword'],
266
-        '2.5.4.36' => ['userCertificate'],
267
-        '2.5.4.37' => ['cACertificate'],
268
-        '2.5.4.38' => ['authorityRevocationList'],
269
-        '2.5.4.39' => ['certificateRevocationList'],
270
-        '2.5.4.40' => ['crossCertificatePair'],
271
-        '2.5.4.41' => ['name'],
272
-        '2.5.4.42' => ['givenName', 'gn'],
273
-        '2.5.4.43' => ['initials'],
274
-        '2.5.4.44' => ['generationQualifier'],
275
-        '2.5.4.45' => ['x500UniqueIdentifier'],
276
-        '2.5.4.46' => ['dnQualifier'],
277
-        '2.5.4.47' => ['enhancedSearchGuide'],
278
-        '2.5.4.48' => ['protocolInformation'],
279
-        '2.5.4.49' => ['distinguishedName'],
280
-        '2.5.4.50' => ['uniqueMember'],
281
-        '2.5.4.51' => ['houseIdentifier'],
282
-        '2.5.4.52' => ['supportedAlgorithms'],
283
-        '2.5.4.53' => ['deltaRevocationList'],
284
-        '2.5.4.54' => ['dmdName'],
285
-        '2.5.4.65' => ['pseudonym'],
286
-        '2.5.18.1' => ['createTimestamp'],
287
-        '2.5.18.2' => ['modifyTimestamp'],
288
-        '2.5.18.3' => ['creatorsName'],
289
-        '2.5.18.4' => ['modifiersName'],
290
-        '2.5.18.5' => ['administrativeRole'],
291
-        '2.5.18.6' => ['subtreeSpecification'],
292
-        '2.5.18.9' => ['hasSubordinates'],
293
-        '2.5.18.10' => ['subschemaSubentry'],
294
-        '2.5.21.1' => ['dITStructureRules'],
295
-        '2.5.21.2' => ['dITContentRules'],
296
-        '2.5.21.4' => ['matchingRules'],
297
-        '2.5.21.5' => ['attributeTypes'],
298
-        '2.5.21.6' => ['objectClasses'],
299
-        '2.5.21.7' => ['nameForms'],
300
-        '2.5.21.8' => ['matchingRuleUse'],
301
-        '2.5.21.9' => ['structuralObjectClass'],
302
-        '2.16.840.1.113730.3.1.1' => ['carLicense'],
303
-        '2.16.840.1.113730.3.1.2' => ['departmentNumber'],
304
-        '2.16.840.1.113730.3.1.3' => ['employeeNumber'],
305
-        '2.16.840.1.113730.3.1.4' => ['employeeType'],
306
-        '2.16.840.1.113730.3.1.34' => ['ref'],
307
-        '2.16.840.1.113730.3.1.39' => ['preferredLanguage'],
308
-        '2.16.840.1.113730.3.1.40' => ['userSMIMECertificate'],
309
-        '2.16.840.1.113730.3.1.216' => ['userPKCS12'],
310
-        '2.16.840.1.113730.3.1.241' => ['displayName'],
311
-    ];
138
+	/**
139
+	 * OID to attribute names mapping.
140
+	 *
141
+	 * First name is the primary name. If there's more than one name, others may
142
+	 * be used as an alias.
143
+	 *
144
+	 * Generated using ldap-attribs.py.
145
+	 *
146
+	 * @internal
147
+	 *
148
+	 * @var array
149
+	 */
150
+	const MAP_OID_TO_NAME = [
151
+		'0.9.2342.19200300.100.1.1' => ['uid', 'userid'],
152
+		'0.9.2342.19200300.100.1.2' => ['textEncodedORAddress'],
153
+		'0.9.2342.19200300.100.1.3' => ['mail', 'rfc822Mailbox'],
154
+		'0.9.2342.19200300.100.1.4' => ['info'],
155
+		'0.9.2342.19200300.100.1.5' => ['drink', 'favouriteDrink'],
156
+		'0.9.2342.19200300.100.1.6' => ['roomNumber'],
157
+		'0.9.2342.19200300.100.1.7' => ['photo'],
158
+		'0.9.2342.19200300.100.1.8' => ['userClass'],
159
+		'0.9.2342.19200300.100.1.9' => ['host'],
160
+		'0.9.2342.19200300.100.1.10' => ['manager'],
161
+		'0.9.2342.19200300.100.1.11' => ['documentIdentifier'],
162
+		'0.9.2342.19200300.100.1.12' => ['documentTitle'],
163
+		'0.9.2342.19200300.100.1.13' => ['documentVersion'],
164
+		'0.9.2342.19200300.100.1.14' => ['documentAuthor'],
165
+		'0.9.2342.19200300.100.1.15' => ['documentLocation'],
166
+		'0.9.2342.19200300.100.1.20' => ['homePhone', 'homeTelephoneNumber'],
167
+		'0.9.2342.19200300.100.1.21' => ['secretary'],
168
+		'0.9.2342.19200300.100.1.22' => ['otherMailbox'],
169
+		'0.9.2342.19200300.100.1.25' => ['dc', 'domainComponent'],
170
+		'0.9.2342.19200300.100.1.26' => ['aRecord'],
171
+		'0.9.2342.19200300.100.1.27' => ['mDRecord'],
172
+		'0.9.2342.19200300.100.1.28' => ['mXRecord'],
173
+		'0.9.2342.19200300.100.1.29' => ['nSRecord'],
174
+		'0.9.2342.19200300.100.1.30' => ['sOARecord'],
175
+		'0.9.2342.19200300.100.1.31' => ['cNAMERecord'],
176
+		'0.9.2342.19200300.100.1.37' => ['associatedDomain'],
177
+		'0.9.2342.19200300.100.1.38' => ['associatedName'],
178
+		'0.9.2342.19200300.100.1.39' => ['homePostalAddress'],
179
+		'0.9.2342.19200300.100.1.40' => ['personalTitle'],
180
+		'0.9.2342.19200300.100.1.41' => ['mobile', 'mobileTelephoneNumber'],
181
+		'0.9.2342.19200300.100.1.42' => ['pager', 'pagerTelephoneNumber'],
182
+		'0.9.2342.19200300.100.1.43' => ['co', 'friendlyCountryName'],
183
+		'0.9.2342.19200300.100.1.44' => ['uniqueIdentifier'],
184
+		'0.9.2342.19200300.100.1.45' => ['organizationalStatus'],
185
+		'0.9.2342.19200300.100.1.46' => ['janetMailbox'],
186
+		'0.9.2342.19200300.100.1.47' => ['mailPreferenceOption'],
187
+		'0.9.2342.19200300.100.1.48' => ['buildingName'],
188
+		'0.9.2342.19200300.100.1.49' => ['dSAQuality'],
189
+		'0.9.2342.19200300.100.1.50' => ['singleLevelQuality'],
190
+		'0.9.2342.19200300.100.1.51' => ['subtreeMinimumQuality'],
191
+		'0.9.2342.19200300.100.1.52' => ['subtreeMaximumQuality'],
192
+		'0.9.2342.19200300.100.1.53' => ['personalSignature'],
193
+		'0.9.2342.19200300.100.1.54' => ['dITRedirect'],
194
+		'0.9.2342.19200300.100.1.55' => ['audio'],
195
+		'0.9.2342.19200300.100.1.56' => ['documentPublisher'],
196
+		'0.9.2342.19200300.100.1.60' => ['jpegPhoto'],
197
+		'1.2.840.113549.1.9.1' => ['email', 'emailAddress', 'pkcs9email'],
198
+		'1.2.840.113556.1.2.102' => ['memberOf'],
199
+		'1.3.6.1.1.1.1.0' => ['uidNumber'],
200
+		'1.3.6.1.1.1.1.1' => ['gidNumber'],
201
+		'1.3.6.1.1.1.1.2' => ['gecos'],
202
+		'1.3.6.1.1.1.1.3' => ['homeDirectory'],
203
+		'1.3.6.1.1.1.1.4' => ['loginShell'],
204
+		'1.3.6.1.1.1.1.5' => ['shadowLastChange'],
205
+		'1.3.6.1.1.1.1.6' => ['shadowMin'],
206
+		'1.3.6.1.1.1.1.7' => ['shadowMax'],
207
+		'1.3.6.1.1.1.1.8' => ['shadowWarning'],
208
+		'1.3.6.1.1.1.1.9' => ['shadowInactive'],
209
+		'1.3.6.1.1.1.1.10' => ['shadowExpire'],
210
+		'1.3.6.1.1.1.1.11' => ['shadowFlag'],
211
+		'1.3.6.1.1.1.1.12' => ['memberUid'],
212
+		'1.3.6.1.1.1.1.13' => ['memberNisNetgroup'],
213
+		'1.3.6.1.1.1.1.14' => ['nisNetgroupTriple'],
214
+		'1.3.6.1.1.1.1.15' => ['ipServicePort'],
215
+		'1.3.6.1.1.1.1.16' => ['ipServiceProtocol'],
216
+		'1.3.6.1.1.1.1.17' => ['ipProtocolNumber'],
217
+		'1.3.6.1.1.1.1.18' => ['oncRpcNumber'],
218
+		'1.3.6.1.1.1.1.19' => ['ipHostNumber'],
219
+		'1.3.6.1.1.1.1.20' => ['ipNetworkNumber'],
220
+		'1.3.6.1.1.1.1.21' => ['ipNetmaskNumber'],
221
+		'1.3.6.1.1.1.1.22' => ['macAddress'],
222
+		'1.3.6.1.1.1.1.23' => ['bootParameter'],
223
+		'1.3.6.1.1.1.1.24' => ['bootFile'],
224
+		'1.3.6.1.1.1.1.26' => ['nisMapName'],
225
+		'1.3.6.1.1.1.1.27' => ['nisMapEntry'],
226
+		'1.3.6.1.1.4' => ['vendorName'],
227
+		'1.3.6.1.1.5' => ['vendorVersion'],
228
+		'1.3.6.1.1.16.4' => ['entryUUID'],
229
+		'1.3.6.1.1.20' => ['entryDN'],
230
+		'2.5.4.0' => ['objectClass'],
231
+		'2.5.4.1' => ['aliasedObjectName', 'aliasedEntryName'],
232
+		'2.5.4.2' => ['knowledgeInformation'],
233
+		'2.5.4.3' => ['cn', 'commonName'],
234
+		'2.5.4.4' => ['sn', 'surname'],
235
+		'2.5.4.5' => ['serialNumber'],
236
+		'2.5.4.6' => ['c', 'countryName'],
237
+		'2.5.4.7' => ['l', 'localityName'],
238
+		'2.5.4.8' => ['st', 'stateOrProvinceName'],
239
+		'2.5.4.9' => ['street', 'streetAddress'],
240
+		'2.5.4.10' => ['o', 'organizationName'],
241
+		'2.5.4.11' => ['ou', 'organizationalUnitName'],
242
+		'2.5.4.12' => ['title'],
243
+		'2.5.4.13' => ['description'],
244
+		'2.5.4.14' => ['searchGuide'],
245
+		'2.5.4.15' => ['businessCategory'],
246
+		'2.5.4.16' => ['postalAddress'],
247
+		'2.5.4.17' => ['postalCode'],
248
+		'2.5.4.18' => ['postOfficeBox'],
249
+		'2.5.4.19' => ['physicalDeliveryOfficeName'],
250
+		'2.5.4.20' => ['telephoneNumber'],
251
+		'2.5.4.21' => ['telexNumber'],
252
+		'2.5.4.22' => ['teletexTerminalIdentifier'],
253
+		'2.5.4.23' => ['facsimileTelephoneNumber', 'fax'],
254
+		'2.5.4.24' => ['x121Address'],
255
+		'2.5.4.25' => ['internationaliSDNNumber'],
256
+		'2.5.4.26' => ['registeredAddress'],
257
+		'2.5.4.27' => ['destinationIndicator'],
258
+		'2.5.4.28' => ['preferredDeliveryMethod'],
259
+		'2.5.4.29' => ['presentationAddress'],
260
+		'2.5.4.30' => ['supportedApplicationContext'],
261
+		'2.5.4.31' => ['member'],
262
+		'2.5.4.32' => ['owner'],
263
+		'2.5.4.33' => ['roleOccupant'],
264
+		'2.5.4.34' => ['seeAlso'],
265
+		'2.5.4.35' => ['userPassword'],
266
+		'2.5.4.36' => ['userCertificate'],
267
+		'2.5.4.37' => ['cACertificate'],
268
+		'2.5.4.38' => ['authorityRevocationList'],
269
+		'2.5.4.39' => ['certificateRevocationList'],
270
+		'2.5.4.40' => ['crossCertificatePair'],
271
+		'2.5.4.41' => ['name'],
272
+		'2.5.4.42' => ['givenName', 'gn'],
273
+		'2.5.4.43' => ['initials'],
274
+		'2.5.4.44' => ['generationQualifier'],
275
+		'2.5.4.45' => ['x500UniqueIdentifier'],
276
+		'2.5.4.46' => ['dnQualifier'],
277
+		'2.5.4.47' => ['enhancedSearchGuide'],
278
+		'2.5.4.48' => ['protocolInformation'],
279
+		'2.5.4.49' => ['distinguishedName'],
280
+		'2.5.4.50' => ['uniqueMember'],
281
+		'2.5.4.51' => ['houseIdentifier'],
282
+		'2.5.4.52' => ['supportedAlgorithms'],
283
+		'2.5.4.53' => ['deltaRevocationList'],
284
+		'2.5.4.54' => ['dmdName'],
285
+		'2.5.4.65' => ['pseudonym'],
286
+		'2.5.18.1' => ['createTimestamp'],
287
+		'2.5.18.2' => ['modifyTimestamp'],
288
+		'2.5.18.3' => ['creatorsName'],
289
+		'2.5.18.4' => ['modifiersName'],
290
+		'2.5.18.5' => ['administrativeRole'],
291
+		'2.5.18.6' => ['subtreeSpecification'],
292
+		'2.5.18.9' => ['hasSubordinates'],
293
+		'2.5.18.10' => ['subschemaSubentry'],
294
+		'2.5.21.1' => ['dITStructureRules'],
295
+		'2.5.21.2' => ['dITContentRules'],
296
+		'2.5.21.4' => ['matchingRules'],
297
+		'2.5.21.5' => ['attributeTypes'],
298
+		'2.5.21.6' => ['objectClasses'],
299
+		'2.5.21.7' => ['nameForms'],
300
+		'2.5.21.8' => ['matchingRuleUse'],
301
+		'2.5.21.9' => ['structuralObjectClass'],
302
+		'2.16.840.1.113730.3.1.1' => ['carLicense'],
303
+		'2.16.840.1.113730.3.1.2' => ['departmentNumber'],
304
+		'2.16.840.1.113730.3.1.3' => ['employeeNumber'],
305
+		'2.16.840.1.113730.3.1.4' => ['employeeType'],
306
+		'2.16.840.1.113730.3.1.34' => ['ref'],
307
+		'2.16.840.1.113730.3.1.39' => ['preferredLanguage'],
308
+		'2.16.840.1.113730.3.1.40' => ['userSMIMECertificate'],
309
+		'2.16.840.1.113730.3.1.216' => ['userPKCS12'],
310
+		'2.16.840.1.113730.3.1.241' => ['displayName'],
311
+	];
312 312
 
313
-    /**
314
-     * OID of the attribute.
315
-     *
316
-     * @var string
317
-     */
318
-    protected $_oid;
313
+	/**
314
+	 * OID of the attribute.
315
+	 *
316
+	 * @var string
317
+	 */
318
+	protected $_oid;
319 319
 
320
-    /**
321
-     * Constructor.
322
-     *
323
-     * @param string $oid OID in dotted format
324
-     */
325
-    public function __construct(string $oid)
326
-    {
327
-        $this->_oid = $oid;
328
-    }
320
+	/**
321
+	 * Constructor.
322
+	 *
323
+	 * @param string $oid OID in dotted format
324
+	 */
325
+	public function __construct(string $oid)
326
+	{
327
+		$this->_oid = $oid;
328
+	}
329 329
 
330
-    /**
331
-     * Initialize from ASN.1.
332
-     *
333
-     * @param ObjectIdentifier $oi
334
-     *
335
-     * @return self
336
-     */
337
-    public static function fromASN1(ObjectIdentifier $oi): self
338
-    {
339
-        return new self($oi->oid());
340
-    }
330
+	/**
331
+	 * Initialize from ASN.1.
332
+	 *
333
+	 * @param ObjectIdentifier $oi
334
+	 *
335
+	 * @return self
336
+	 */
337
+	public static function fromASN1(ObjectIdentifier $oi): self
338
+	{
339
+		return new self($oi->oid());
340
+	}
341 341
 
342
-    /**
343
-     * Initialize from attribute name.
344
-     *
345
-     * @param string $name
346
-     *
347
-     * @return self
348
-     */
349
-    public static function fromName(string $name): self
350
-    {
351
-        $oid = self::attrNameToOID($name);
352
-        return new self($oid);
353
-    }
342
+	/**
343
+	 * Initialize from attribute name.
344
+	 *
345
+	 * @param string $name
346
+	 *
347
+	 * @return self
348
+	 */
349
+	public static function fromName(string $name): self
350
+	{
351
+		$oid = self::attrNameToOID($name);
352
+		return new self($oid);
353
+	}
354 354
 
355
-    /**
356
-     * Get OID of the attribute.
357
-     *
358
-     * @return string OID in dotted format
359
-     */
360
-    public function oid(): string
361
-    {
362
-        return $this->_oid;
363
-    }
355
+	/**
356
+	 * Get OID of the attribute.
357
+	 *
358
+	 * @return string OID in dotted format
359
+	 */
360
+	public function oid(): string
361
+	{
362
+		return $this->_oid;
363
+	}
364 364
 
365
-    /**
366
-     * Get name of the attribute.
367
-     *
368
-     * @return string
369
-     */
370
-    public function typeName(): string
371
-    {
372
-        if (array_key_exists($this->_oid, self::MAP_OID_TO_NAME)) {
373
-            return self::MAP_OID_TO_NAME[$this->_oid][0];
374
-        }
375
-        return $this->_oid;
376
-    }
365
+	/**
366
+	 * Get name of the attribute.
367
+	 *
368
+	 * @return string
369
+	 */
370
+	public function typeName(): string
371
+	{
372
+		if (array_key_exists($this->_oid, self::MAP_OID_TO_NAME)) {
373
+			return self::MAP_OID_TO_NAME[$this->_oid][0];
374
+		}
375
+		return $this->_oid;
376
+	}
377 377
 
378
-    /**
379
-     * Generate ASN.1 element.
380
-     *
381
-     * @return ObjectIdentifier
382
-     */
383
-    public function toASN1(): ObjectIdentifier
384
-    {
385
-        return new ObjectIdentifier($this->_oid);
386
-    }
378
+	/**
379
+	 * Generate ASN.1 element.
380
+	 *
381
+	 * @return ObjectIdentifier
382
+	 */
383
+	public function toASN1(): ObjectIdentifier
384
+	{
385
+		return new ObjectIdentifier($this->_oid);
386
+	}
387 387
 
388
-    /**
389
-     * Convert attribute name to OID.
390
-     *
391
-     * @param string $name Primary attribute name or an alias
392
-     *
393
-     * @throws \OutOfBoundsException
394
-     *
395
-     * @return string OID in dotted format
396
-     */
397
-    public static function attrNameToOID(string $name): string
398
-    {
399
-        // if already in OID form
400
-        if (preg_match('/^[0-9]+(?:\.[0-9]+)*$/', $name)) {
401
-            return $name;
402
-        }
403
-        $map = self::_oidReverseMap();
404
-        $k = strtolower($name);
405
-        if (!isset($map[$k])) {
406
-            throw new \OutOfBoundsException("No OID for {$name}.");
407
-        }
408
-        return $map[$k];
409
-    }
388
+	/**
389
+	 * Convert attribute name to OID.
390
+	 *
391
+	 * @param string $name Primary attribute name or an alias
392
+	 *
393
+	 * @throws \OutOfBoundsException
394
+	 *
395
+	 * @return string OID in dotted format
396
+	 */
397
+	public static function attrNameToOID(string $name): string
398
+	{
399
+		// if already in OID form
400
+		if (preg_match('/^[0-9]+(?:\.[0-9]+)*$/', $name)) {
401
+			return $name;
402
+		}
403
+		$map = self::_oidReverseMap();
404
+		$k = strtolower($name);
405
+		if (!isset($map[$k])) {
406
+			throw new \OutOfBoundsException("No OID for {$name}.");
407
+		}
408
+		return $map[$k];
409
+	}
410 410
 
411
-    /**
412
-     * Get ASN.1 string for given attribute type.
413
-     *
414
-     * @param string $oid Attribute OID
415
-     * @param string $str String
416
-     *
417
-     * @throws \LogicException
418
-     *
419
-     * @return StringType
420
-     */
421
-    public static function asn1StringForType(string $oid, string $str): StringType
422
-    {
423
-        if (!array_key_exists($oid, self::MAP_ATTR_TO_STR_TYPE)) {
424
-            return new UTF8String($str);
425
-        }
426
-        switch (self::MAP_ATTR_TO_STR_TYPE[$oid]) {
427
-            case Element::TYPE_PRINTABLE_STRING:
428
-                return new PrintableString($str);
429
-            // @codeCoverageIgnoreStart
430
-            default:
431
-                // only reachable during development
432
-                throw new \LogicException();
433
-        }
434
-        // @codeCoverageIgnoreEnd
435
-    }
411
+	/**
412
+	 * Get ASN.1 string for given attribute type.
413
+	 *
414
+	 * @param string $oid Attribute OID
415
+	 * @param string $str String
416
+	 *
417
+	 * @throws \LogicException
418
+	 *
419
+	 * @return StringType
420
+	 */
421
+	public static function asn1StringForType(string $oid, string $str): StringType
422
+	{
423
+		if (!array_key_exists($oid, self::MAP_ATTR_TO_STR_TYPE)) {
424
+			return new UTF8String($str);
425
+		}
426
+		switch (self::MAP_ATTR_TO_STR_TYPE[$oid]) {
427
+			case Element::TYPE_PRINTABLE_STRING:
428
+				return new PrintableString($str);
429
+			// @codeCoverageIgnoreStart
430
+			default:
431
+				// only reachable during development
432
+				throw new \LogicException();
433
+		}
434
+		// @codeCoverageIgnoreEnd
435
+	}
436 436
 
437
-    /**
438
-     * Get name to OID lookup map.
439
-     *
440
-     * @return array
441
-     */
442
-    private static function _oidReverseMap(): array
443
-    {
444
-        static $map;
445
-        if (!isset($map)) {
446
-            $map = [];
447
-            // for each attribute type
448
-            foreach (self::MAP_OID_TO_NAME as $oid => $names) {
449
-                // for primary name and aliases
450
-                foreach ($names as $name) {
451
-                    $map[strtolower($name)] = $oid;
452
-                }
453
-            }
454
-        }
455
-        return $map;
456
-    }
437
+	/**
438
+	 * Get name to OID lookup map.
439
+	 *
440
+	 * @return array
441
+	 */
442
+	private static function _oidReverseMap(): array
443
+	{
444
+		static $map;
445
+		if (!isset($map)) {
446
+			$map = [];
447
+			// for each attribute type
448
+			foreach (self::MAP_OID_TO_NAME as $oid => $names) {
449
+				// for primary name and aliases
450
+				foreach ($names as $name) {
451
+					$map[strtolower($name)] = $oid;
452
+				}
453
+			}
454
+		}
455
+		return $map;
456
+	}
457 457
 }
Please login to merge, or discard this patch.
lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php 1 patch
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -24,156 +24,156 @@
 block discarded – undo
24 24
  */
25 25
 abstract class DirectoryString extends AttributeValue
26 26
 {
27
-    /**
28
-     * Teletex string syntax.
29
-     *
30
-     * @var int
31
-     */
32
-    const TELETEX = Element::TYPE_T61_STRING;
33
-
34
-    /**
35
-     * Printable string syntax.
36
-     *
37
-     * @var int
38
-     */
39
-    const PRINTABLE = Element::TYPE_PRINTABLE_STRING;
40
-
41
-    /**
42
-     * BMP string syntax.
43
-     *
44
-     * @var int
45
-     */
46
-    const BMP = Element::TYPE_BMP_STRING;
47
-
48
-    /**
49
-     * Universal string syntax.
50
-     *
51
-     * @var int
52
-     */
53
-    const UNIVERSAL = Element::TYPE_UNIVERSAL_STRING;
54
-
55
-    /**
56
-     * UTF-8 string syntax.
57
-     *
58
-     * @var int
59
-     */
60
-    const UTF8 = Element::TYPE_UTF8_STRING;
61
-
62
-    /**
63
-     * Mapping from syntax enumeration to ASN.1 class name.
64
-     *
65
-     * @internal
66
-     *
67
-     * @var array
68
-     */
69
-    const MAP_TAG_TO_CLASS = [
70
-        self::TELETEX => T61String::class,
71
-        self::PRINTABLE => PrintableString::class,
72
-        self::UNIVERSAL => UniversalString::class,
73
-        self::UTF8 => UTF8String::class,
74
-        self::BMP => BMPString::class,
75
-    ];
76
-
77
-    /**
78
-     * ASN.1 type tag for the chosen syntax.
79
-     *
80
-     * @var int
81
-     */
82
-    protected $_stringTag;
83
-
84
-    /**
85
-     * String value.
86
-     *
87
-     * @var string
88
-     */
89
-    protected $_string;
90
-
91
-    /**
92
-     * Constructor.
93
-     *
94
-     * @param string $value      String value
95
-     * @param int    $string_tag Syntax choice
96
-     */
97
-    public function __construct(string $value, int $string_tag)
98
-    {
99
-        $this->_string = $value;
100
-        $this->_stringTag = $string_tag;
101
-    }
102
-
103
-    /**
104
-     * {@inheritdoc}
105
-     *
106
-     * @return self
107
-     */
108
-    public static function fromASN1(UnspecifiedType $el): AttributeValue
109
-    {
110
-        $tag = $el->tag();
111
-        self::_tagToASN1Class($tag);
112
-        return new static($el->asString()->string(), $tag);
113
-    }
114
-
115
-    /**
116
-     * {@inheritdoc}
117
-     */
118
-    public function toASN1(): Element
119
-    {
120
-        $cls = self::_tagToASN1Class($this->_stringTag);
121
-        return new $cls($this->_string);
122
-    }
123
-
124
-    /**
125
-     * {@inheritdoc}
126
-     */
127
-    public function stringValue(): string
128
-    {
129
-        return $this->_string;
130
-    }
131
-
132
-    /**
133
-     * {@inheritdoc}
134
-     */
135
-    public function equalityMatchingRule(): MatchingRule
136
-    {
137
-        return new CaseIgnoreMatch($this->_stringTag);
138
-    }
139
-
140
-    /**
141
-     * {@inheritdoc}
142
-     */
143
-    public function rfc2253String(): string
144
-    {
145
-        // TeletexString is encoded as binary
146
-        if (self::TELETEX === $this->_stringTag) {
147
-            return $this->_transcodedString();
148
-        }
149
-        return DNParser::escapeString($this->_transcodedString());
150
-    }
151
-
152
-    /**
153
-     * {@inheritdoc}
154
-     */
155
-    protected function _transcodedString(): string
156
-    {
157
-        $step = new TranscodeStep($this->_stringTag);
158
-        return $step->apply($this->_string);
159
-    }
160
-
161
-    /**
162
-     * Get ASN.1 class name for given DirectoryString type tag.
163
-     *
164
-     * @param int $tag
165
-     *
166
-     * @throws \UnexpectedValueException
167
-     *
168
-     * @return string
169
-     */
170
-    private static function _tagToASN1Class(int $tag): string
171
-    {
172
-        if (!array_key_exists($tag, self::MAP_TAG_TO_CLASS)) {
173
-            throw new \UnexpectedValueException(
174
-                'Type ' . Element::tagToName($tag) .
175
-                ' is not valid DirectoryString.');
176
-        }
177
-        return self::MAP_TAG_TO_CLASS[$tag];
178
-    }
27
+	/**
28
+	 * Teletex string syntax.
29
+	 *
30
+	 * @var int
31
+	 */
32
+	const TELETEX = Element::TYPE_T61_STRING;
33
+
34
+	/**
35
+	 * Printable string syntax.
36
+	 *
37
+	 * @var int
38
+	 */
39
+	const PRINTABLE = Element::TYPE_PRINTABLE_STRING;
40
+
41
+	/**
42
+	 * BMP string syntax.
43
+	 *
44
+	 * @var int
45
+	 */
46
+	const BMP = Element::TYPE_BMP_STRING;
47
+
48
+	/**
49
+	 * Universal string syntax.
50
+	 *
51
+	 * @var int
52
+	 */
53
+	const UNIVERSAL = Element::TYPE_UNIVERSAL_STRING;
54
+
55
+	/**
56
+	 * UTF-8 string syntax.
57
+	 *
58
+	 * @var int
59
+	 */
60
+	const UTF8 = Element::TYPE_UTF8_STRING;
61
+
62
+	/**
63
+	 * Mapping from syntax enumeration to ASN.1 class name.
64
+	 *
65
+	 * @internal
66
+	 *
67
+	 * @var array
68
+	 */
69
+	const MAP_TAG_TO_CLASS = [
70
+		self::TELETEX => T61String::class,
71
+		self::PRINTABLE => PrintableString::class,
72
+		self::UNIVERSAL => UniversalString::class,
73
+		self::UTF8 => UTF8String::class,
74
+		self::BMP => BMPString::class,
75
+	];
76
+
77
+	/**
78
+	 * ASN.1 type tag for the chosen syntax.
79
+	 *
80
+	 * @var int
81
+	 */
82
+	protected $_stringTag;
83
+
84
+	/**
85
+	 * String value.
86
+	 *
87
+	 * @var string
88
+	 */
89
+	protected $_string;
90
+
91
+	/**
92
+	 * Constructor.
93
+	 *
94
+	 * @param string $value      String value
95
+	 * @param int    $string_tag Syntax choice
96
+	 */
97
+	public function __construct(string $value, int $string_tag)
98
+	{
99
+		$this->_string = $value;
100
+		$this->_stringTag = $string_tag;
101
+	}
102
+
103
+	/**
104
+	 * {@inheritdoc}
105
+	 *
106
+	 * @return self
107
+	 */
108
+	public static function fromASN1(UnspecifiedType $el): AttributeValue
109
+	{
110
+		$tag = $el->tag();
111
+		self::_tagToASN1Class($tag);
112
+		return new static($el->asString()->string(), $tag);
113
+	}
114
+
115
+	/**
116
+	 * {@inheritdoc}
117
+	 */
118
+	public function toASN1(): Element
119
+	{
120
+		$cls = self::_tagToASN1Class($this->_stringTag);
121
+		return new $cls($this->_string);
122
+	}
123
+
124
+	/**
125
+	 * {@inheritdoc}
126
+	 */
127
+	public function stringValue(): string
128
+	{
129
+		return $this->_string;
130
+	}
131
+
132
+	/**
133
+	 * {@inheritdoc}
134
+	 */
135
+	public function equalityMatchingRule(): MatchingRule
136
+	{
137
+		return new CaseIgnoreMatch($this->_stringTag);
138
+	}
139
+
140
+	/**
141
+	 * {@inheritdoc}
142
+	 */
143
+	public function rfc2253String(): string
144
+	{
145
+		// TeletexString is encoded as binary
146
+		if (self::TELETEX === $this->_stringTag) {
147
+			return $this->_transcodedString();
148
+		}
149
+		return DNParser::escapeString($this->_transcodedString());
150
+	}
151
+
152
+	/**
153
+	 * {@inheritdoc}
154
+	 */
155
+	protected function _transcodedString(): string
156
+	{
157
+		$step = new TranscodeStep($this->_stringTag);
158
+		return $step->apply($this->_string);
159
+	}
160
+
161
+	/**
162
+	 * Get ASN.1 class name for given DirectoryString type tag.
163
+	 *
164
+	 * @param int $tag
165
+	 *
166
+	 * @throws \UnexpectedValueException
167
+	 *
168
+	 * @return string
169
+	 */
170
+	private static function _tagToASN1Class(int $tag): string
171
+	{
172
+		if (!array_key_exists($tag, self::MAP_TAG_TO_CLASS)) {
173
+			throw new \UnexpectedValueException(
174
+				'Type ' . Element::tagToName($tag) .
175
+				' is not valid DirectoryString.');
176
+		}
177
+		return self::MAP_TAG_TO_CLASS[$tag];
178
+	}
179 179
 }
Please login to merge, or discard this patch.
lib/X501/ASN1/Attribute.php 2 patches
Indentation   +147 added lines, -147 removed lines patch added patch discarded remove patch
@@ -17,161 +17,161 @@
 block discarded – undo
17 17
  */
18 18
 class Attribute implements \Countable, \IteratorAggregate
19 19
 {
20
-    use TypedAttribute;
20
+	use TypedAttribute;
21 21
 
22
-    /**
23
-     * Attribute values.
24
-     *
25
-     * @var AttributeValue[]
26
-     */
27
-    protected $_values;
22
+	/**
23
+	 * Attribute values.
24
+	 *
25
+	 * @var AttributeValue[]
26
+	 */
27
+	protected $_values;
28 28
 
29
-    /**
30
-     * Constructor.
31
-     *
32
-     * @param AttributeType  $type      Attribute type
33
-     * @param AttributeValue ...$values Attribute values
34
-     */
35
-    public function __construct(AttributeType $type, AttributeValue ...$values)
36
-    {
37
-        // check that attribute values have correct oid
38
-        array_walk($values,
39
-            function (AttributeValue $value) use ($type) {
40
-                if ($value->oid() !== $type->oid()) {
41
-                    throw new \LogicException('Attribute OID mismatch.');
42
-                }
43
-            });
44
-        $this->_type = $type;
45
-        $this->_values = $values;
46
-    }
29
+	/**
30
+	 * Constructor.
31
+	 *
32
+	 * @param AttributeType  $type      Attribute type
33
+	 * @param AttributeValue ...$values Attribute values
34
+	 */
35
+	public function __construct(AttributeType $type, AttributeValue ...$values)
36
+	{
37
+		// check that attribute values have correct oid
38
+		array_walk($values,
39
+			function (AttributeValue $value) use ($type) {
40
+				if ($value->oid() !== $type->oid()) {
41
+					throw new \LogicException('Attribute OID mismatch.');
42
+				}
43
+			});
44
+		$this->_type = $type;
45
+		$this->_values = $values;
46
+	}
47 47
 
48
-    /**
49
-     * Initialize from ASN.1.
50
-     *
51
-     * @param Sequence $seq
52
-     *
53
-     * @return self
54
-     */
55
-    public static function fromASN1(Sequence $seq): self
56
-    {
57
-        $type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier());
58
-        $values = array_map(
59
-            function (UnspecifiedType $el) use ($type) {
60
-                return AttributeValue::fromASN1ByOID($type->oid(), $el);
61
-            }, $seq->at(1)->asSet()->elements());
62
-        return new self($type, ...$values);
63
-    }
48
+	/**
49
+	 * Initialize from ASN.1.
50
+	 *
51
+	 * @param Sequence $seq
52
+	 *
53
+	 * @return self
54
+	 */
55
+	public static function fromASN1(Sequence $seq): self
56
+	{
57
+		$type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier());
58
+		$values = array_map(
59
+			function (UnspecifiedType $el) use ($type) {
60
+				return AttributeValue::fromASN1ByOID($type->oid(), $el);
61
+			}, $seq->at(1)->asSet()->elements());
62
+		return new self($type, ...$values);
63
+	}
64 64
 
65
-    /**
66
-     * Convenience method to initialize from attribute values.
67
-     *
68
-     * @param AttributeValue ...$values One or more values
69
-     *
70
-     * @throws \LogicException
71
-     *
72
-     * @return self
73
-     */
74
-    public static function fromAttributeValues(AttributeValue ...$values): self
75
-    {
76
-        // we need at least one value to determine OID
77
-        if (!count($values)) {
78
-            throw new \LogicException('No values.');
79
-        }
80
-        $oid = reset($values)->oid();
81
-        return new self(new AttributeType($oid), ...$values);
82
-    }
65
+	/**
66
+	 * Convenience method to initialize from attribute values.
67
+	 *
68
+	 * @param AttributeValue ...$values One or more values
69
+	 *
70
+	 * @throws \LogicException
71
+	 *
72
+	 * @return self
73
+	 */
74
+	public static function fromAttributeValues(AttributeValue ...$values): self
75
+	{
76
+		// we need at least one value to determine OID
77
+		if (!count($values)) {
78
+			throw new \LogicException('No values.');
79
+		}
80
+		$oid = reset($values)->oid();
81
+		return new self(new AttributeType($oid), ...$values);
82
+	}
83 83
 
84
-    /**
85
-     * Get first value of the attribute.
86
-     *
87
-     * @throws \LogicException
88
-     *
89
-     * @return AttributeValue
90
-     */
91
-    public function first(): AttributeValue
92
-    {
93
-        if (!count($this->_values)) {
94
-            throw new \LogicException('Attribute contains no values.');
95
-        }
96
-        return $this->_values[0];
97
-    }
84
+	/**
85
+	 * Get first value of the attribute.
86
+	 *
87
+	 * @throws \LogicException
88
+	 *
89
+	 * @return AttributeValue
90
+	 */
91
+	public function first(): AttributeValue
92
+	{
93
+		if (!count($this->_values)) {
94
+			throw new \LogicException('Attribute contains no values.');
95
+		}
96
+		return $this->_values[0];
97
+	}
98 98
 
99
-    /**
100
-     * Get all values.
101
-     *
102
-     * @return AttributeValue[]
103
-     */
104
-    public function values(): array
105
-    {
106
-        return $this->_values;
107
-    }
99
+	/**
100
+	 * Get all values.
101
+	 *
102
+	 * @return AttributeValue[]
103
+	 */
104
+	public function values(): array
105
+	{
106
+		return $this->_values;
107
+	}
108 108
 
109
-    /**
110
-     * Generate ASN.1 structure.
111
-     *
112
-     * @return Sequence
113
-     */
114
-    public function toASN1(): Sequence
115
-    {
116
-        $values = array_map(
117
-            function (AttributeValue $value) {
118
-                return $value->toASN1();
119
-            }, $this->_values);
120
-        $valueset = new Set(...$values);
121
-        return new Sequence($this->_type->toASN1(), $valueset->sortedSetOf());
122
-    }
109
+	/**
110
+	 * Generate ASN.1 structure.
111
+	 *
112
+	 * @return Sequence
113
+	 */
114
+	public function toASN1(): Sequence
115
+	{
116
+		$values = array_map(
117
+			function (AttributeValue $value) {
118
+				return $value->toASN1();
119
+			}, $this->_values);
120
+		$valueset = new Set(...$values);
121
+		return new Sequence($this->_type->toASN1(), $valueset->sortedSetOf());
122
+	}
123 123
 
124
-    /**
125
-     * Cast attribute values to another AttributeValue class.
126
-     *
127
-     * This method is generally used to cast UnknownAttributeValue values
128
-     * to specific objects when class is declared outside this package.
129
-     *
130
-     * The new class must be derived from AttributeValue and have the same OID
131
-     * as current attribute values.
132
-     *
133
-     * @param string $cls AttributeValue class name
134
-     *
135
-     * @throws \LogicException
136
-     *
137
-     * @return self
138
-     */
139
-    public function castValues(string $cls): self
140
-    {
141
-        $refl = new \ReflectionClass($cls);
142
-        if (!$refl->isSubclassOf(AttributeValue::class)) {
143
-            throw new \LogicException(
144
-                "{$cls} must be derived from " . AttributeValue::class . '.');
145
-        }
146
-        $oid = $this->oid();
147
-        $values = array_map(
148
-            function (AttributeValue $value) use ($cls, $oid) {
149
-                $value = $cls::fromSelf($value);
150
-                if ($value->oid() !== $oid) {
151
-                    throw new \LogicException('Attribute OID mismatch.');
152
-                }
153
-                return $value;
154
-            }, $this->_values);
155
-        return self::fromAttributeValues(...$values);
156
-    }
124
+	/**
125
+	 * Cast attribute values to another AttributeValue class.
126
+	 *
127
+	 * This method is generally used to cast UnknownAttributeValue values
128
+	 * to specific objects when class is declared outside this package.
129
+	 *
130
+	 * The new class must be derived from AttributeValue and have the same OID
131
+	 * as current attribute values.
132
+	 *
133
+	 * @param string $cls AttributeValue class name
134
+	 *
135
+	 * @throws \LogicException
136
+	 *
137
+	 * @return self
138
+	 */
139
+	public function castValues(string $cls): self
140
+	{
141
+		$refl = new \ReflectionClass($cls);
142
+		if (!$refl->isSubclassOf(AttributeValue::class)) {
143
+			throw new \LogicException(
144
+				"{$cls} must be derived from " . AttributeValue::class . '.');
145
+		}
146
+		$oid = $this->oid();
147
+		$values = array_map(
148
+			function (AttributeValue $value) use ($cls, $oid) {
149
+				$value = $cls::fromSelf($value);
150
+				if ($value->oid() !== $oid) {
151
+					throw new \LogicException('Attribute OID mismatch.');
152
+				}
153
+				return $value;
154
+			}, $this->_values);
155
+		return self::fromAttributeValues(...$values);
156
+	}
157 157
 
158
-    /**
159
-     * @see \Countable::count()
160
-     *
161
-     * @return int
162
-     */
163
-    public function count(): int
164
-    {
165
-        return count($this->_values);
166
-    }
158
+	/**
159
+	 * @see \Countable::count()
160
+	 *
161
+	 * @return int
162
+	 */
163
+	public function count(): int
164
+	{
165
+		return count($this->_values);
166
+	}
167 167
 
168
-    /**
169
-     * @see \IteratorAggregate::getIterator()
170
-     *
171
-     * @return \ArrayIterator
172
-     */
173
-    public function getIterator(): \ArrayIterator
174
-    {
175
-        return new \ArrayIterator($this->_values);
176
-    }
168
+	/**
169
+	 * @see \IteratorAggregate::getIterator()
170
+	 *
171
+	 * @return \ArrayIterator
172
+	 */
173
+	public function getIterator(): \ArrayIterator
174
+	{
175
+		return new \ArrayIterator($this->_values);
176
+	}
177 177
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X501\ASN1;
6 6
 
@@ -36,7 +36,7 @@  discard block
 block discarded – undo
36 36
     {
37 37
         // check that attribute values have correct oid
38 38
         array_walk($values,
39
-            function (AttributeValue $value) use ($type) {
39
+            function(AttributeValue $value) use ($type) {
40 40
                 if ($value->oid() !== $type->oid()) {
41 41
                     throw new \LogicException('Attribute OID mismatch.');
42 42
                 }
@@ -56,7 +56,7 @@  discard block
 block discarded – undo
56 56
     {
57 57
         $type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier());
58 58
         $values = array_map(
59
-            function (UnspecifiedType $el) use ($type) {
59
+            function(UnspecifiedType $el) use ($type) {
60 60
                 return AttributeValue::fromASN1ByOID($type->oid(), $el);
61 61
             }, $seq->at(1)->asSet()->elements());
62 62
         return new self($type, ...$values);
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
     public function toASN1(): Sequence
115 115
     {
116 116
         $values = array_map(
117
-            function (AttributeValue $value) {
117
+            function(AttributeValue $value) {
118 118
                 return $value->toASN1();
119 119
             }, $this->_values);
120 120
         $valueset = new Set(...$values);
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
         }
146 146
         $oid = $this->oid();
147 147
         $values = array_map(
148
-            function (AttributeValue $value) use ($cls, $oid) {
148
+            function(AttributeValue $value) use ($cls, $oid) {
149 149
                 $value = $cls::fromSelf($value);
150 150
                 if ($value->oid() !== $oid) {
151 151
                     throw new \LogicException('Attribute OID mismatch.');
Please login to merge, or discard this patch.
lib/X501/MatchingRule/StringPrepMatchingRule.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -11,30 +11,30 @@
 block discarded – undo
11 11
  */
12 12
 abstract class StringPrepMatchingRule extends MatchingRule
13 13
 {
14
-    /**
15
-     * String preparer.
16
-     *
17
-     * @var StringPreparer
18
-     */
19
-    protected $_prep;
14
+	/**
15
+	 * String preparer.
16
+	 *
17
+	 * @var StringPreparer
18
+	 */
19
+	protected $_prep;
20 20
 
21
-    /**
22
-     * Constructor.
23
-     *
24
-     * @param StringPreparer $preparer
25
-     */
26
-    public function __construct(StringPreparer $preparer)
27
-    {
28
-        $this->_prep = $preparer;
29
-    }
21
+	/**
22
+	 * Constructor.
23
+	 *
24
+	 * @param StringPreparer $preparer
25
+	 */
26
+	public function __construct(StringPreparer $preparer)
27
+	{
28
+		$this->_prep = $preparer;
29
+	}
30 30
 
31
-    /**
32
-     * {@inheritdoc}
33
-     */
34
-    public function compare($assertion, $value): ?bool
35
-    {
36
-        $assertion = $this->_prep->prepare($assertion);
37
-        $value = $this->_prep->prepare($value);
38
-        return 0 === strcmp($assertion, $value);
39
-    }
31
+	/**
32
+	 * {@inheritdoc}
33
+	 */
34
+	public function compare($assertion, $value): ?bool
35
+	{
36
+		$assertion = $this->_prep->prepare($assertion);
37
+		$value = $this->_prep->prepare($value);
38
+		return 0 === strcmp($assertion, $value);
39
+	}
40 40
 }
Please login to merge, or discard this patch.
lib/X501/MatchingRule/BinaryMatch.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -11,11 +11,11 @@
 block discarded – undo
11 11
  */
12 12
 class BinaryMatch extends MatchingRule
13 13
 {
14
-    /**
15
-     * {@inheritdoc}
16
-     */
17
-    public function compare($assertion, $value): ?bool
18
-    {
19
-        return 0 === strcmp($assertion, $value);
20
-    }
14
+	/**
15
+	 * {@inheritdoc}
16
+	 */
17
+	public function compare($assertion, $value): ?bool
18
+	{
19
+		return 0 === strcmp($assertion, $value);
20
+	}
21 21
 }
Please login to merge, or discard this patch.