Attributes::fromASN1()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 14
cts 14
cp 1
rs 9.6666
c 0
b 0
f 0
nc 1
cc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace X509\CertificationRequest;
6
7
use ASN1\Type\UnspecifiedType;
8
use ASN1\Type\Constructed\Set;
9
use X501\ASN1\Attribute;
10
use X501\ASN1\AttributeValue\AttributeValue;
11
use X509\CertificationRequest\Attribute\ExtensionRequestValue;
12
use X509\Feature\AttributeContainer;
13
14
/**
15
 * Implements <i>Attributes</i> ASN.1 type as a <i>SET OF Attribute</i>.
16
 *
17
 * Used in <i>CertificationRequestInfo</i>.
18
 *
19
 * @link https://tools.ietf.org/html/rfc2986#section-4
20
 */
21
class Attributes implements \Countable, \IteratorAggregate
22
{
23
    use AttributeContainer;
24
    
25
    /**
26
     * Mapping from OID to attribute value class name.
27
     *
28
     * @internal
29
     *
30
     * @var array
31
     */
32
    const MAP_OID_TO_CLASS = array(
33
        /* @formatter:off */
34
        ExtensionRequestValue::OID => ExtensionRequestValue::class
35
        /* @formatter:on */
36
    );
37
    
38
    /**
39
     * Constructor.
40
     *
41
     * @param Attribute ...$attribs Attribute objects
42
     */
43 8
    public function __construct(Attribute ...$attribs)
44
    {
45 8
        $this->_attributes = $attribs;
46 8
    }
47
    
48
    /**
49
     * Initialize from attribute values.
50
     *
51
     * @param AttributeValue ...$values
52
     * @return self
53
     */
54 1
    public static function fromAttributeValues(AttributeValue ...$values): Attributes
55
    {
56 1
        $attribs = array_map(
57 1
            function (AttributeValue $value) {
58 1
                return $value->toAttribute();
59 1
            }, $values);
60 1
        return new self(...$attribs);
61
    }
62
    
63
    /**
64
     * Initialize from ASN.1.
65
     *
66
     * @param Set $set
67
     * @return self
68
     */
69 4
    public static function fromASN1(Set $set): Attributes
70
    {
71 4
        $attribs = array_map(
72 4
            function (UnspecifiedType $el) {
73 4
                return Attribute::fromASN1($el->asSequence());
74 4
            }, $set->elements());
75
        // cast attributes
76 4
        $attribs = array_map(
77 4
            function (Attribute $attr) {
78 4
                $oid = $attr->oid();
79 4
                if (array_key_exists($oid, self::MAP_OID_TO_CLASS)) {
80 4
                    $cls = self::MAP_OID_TO_CLASS[$oid];
81 4
                    return $attr->castValues($cls);
82
                }
83 1
                return $attr;
84 4
            }, $attribs);
85 4
        return new self(...$attribs);
86
    }
87
    
88
    /**
89
     * Check whether extension request attribute is present.
90
     *
91
     * @return bool
92
     */
93 6
    public function hasExtensionRequest(): bool
94
    {
95 6
        return $this->has(ExtensionRequestValue::OID);
96
    }
97
    
98
    /**
99
     * Get extension request attribute value.
100
     *
101
     * @throws \LogicException
102
     * @return ExtensionRequestValue
103
     */
104 4
    public function extensionRequest(): ExtensionRequestValue
105
    {
106 4
        if (!$this->hasExtensionRequest()) {
107 1
            throw new \LogicException("No extension request attribute.");
108
        }
109 3
        return $this->firstOf(ExtensionRequestValue::OID)->first();
110
    }
111
    
112
    /**
113
     * Generate ASN.1 structure.
114
     *
115
     * @return Set
116
     */
117 5
    public function toASN1(): Set
118
    {
119 5
        $elements = array_map(
120 5
            function (Attribute $attr) {
121 5
                return $attr->toASN1();
122 5
            }, array_values($this->_attributes));
123 5
        $set = new Set(...$elements);
124 5
        return $set->sortedSetOf();
125
    }
126
}
127