CertificateChain   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 4
dl 0
loc 130
ccs 34
cts 34
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A fromPEMs() 0 8 1
A fromPEMString() 0 5 1
A certificates() 0 4 1
A endEntityCertificate() 0 7 2
A trustAnchorCertificate() 0 7 2
A certificationPath() 0 4 1
A toPEMString() 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;
6
7
use Sop\CryptoEncoding\PEM;
8
use Sop\CryptoEncoding\PEMBundle;
9
use X509\CertificationPath\CertificationPath;
10
11
/**
12
 * Ordered list of certificates from the end-entity to the trust anchor.
13
 */
14
class CertificateChain implements \Countable, \IteratorAggregate
15
{
16
    /**
17
     * List of certificates in a chain.
18
     *
19
     * @var Certificate[]
20
     */
21
    protected $_certs;
22
    
23
    /**
24
     * Constructor.
25
     *
26
     * @param Certificate ...$certs List of certificates, end-entity first
27
     */
28 7
    public function __construct(Certificate ...$certs)
29
    {
30 7
        $this->_certs = $certs;
31 7
    }
32
    
33
    /**
34
     * Initialize from a list of PEMs.
35
     *
36
     * @param PEM ...$pems
37
     * @return self
38
     */
39 2
    public static function fromPEMs(PEM ...$pems): self
40
    {
41 2
        $certs = array_map(
42 2
            function (PEM $pem) {
43 2
                return Certificate::fromPEM($pem);
44 2
            }, $pems);
45 2
        return new self(...$certs);
46
    }
47
    
48
    /**
49
     * Initialize from a string containing multiple PEM blocks.
50
     *
51
     * @param string $str
52
     * @return self
53
     */
54 1
    public static function fromPEMString(string $str): self
55
    {
56 1
        $pems = PEMBundle::fromString($str)->all();
57 1
        return self::fromPEMs(...$pems);
58
    }
59
    
60
    /**
61
     * Get all certificates in a chain ordered from the end-entity certificate
62
     * to the trust anchor.
63
     *
64
     * @return Certificate[]
65
     */
66 3
    public function certificates(): array
67
    {
68 3
        return $this->_certs;
69
    }
70
    
71
    /**
72
     * Get the end-entity certificate.
73
     *
74
     * @throws \LogicException
75
     * @return Certificate
76
     */
77 2
    public function endEntityCertificate(): Certificate
78
    {
79 2
        if (!count($this->_certs)) {
80 1
            throw new \LogicException("No certificates.");
81
        }
82 1
        return $this->_certs[0];
83
    }
84
    
85
    /**
86
     * Get the trust anchor certificate.
87
     *
88
     * @throws \LogicException
89
     * @return Certificate
90
     */
91 2
    public function trustAnchorCertificate(): Certificate
92
    {
93 2
        if (!count($this->_certs)) {
94 1
            throw new \LogicException("No certificates.");
95
        }
96 1
        return $this->_certs[count($this->_certs) - 1];
97
    }
98
    
99
    /**
100
     * Convert certificate chain to certification path.
101
     *
102
     * @return CertificationPath
103
     */
104 1
    public function certificationPath(): CertificationPath
105
    {
106 1
        return CertificationPath::fromCertificateChain($this);
107
    }
108
    
109
    /**
110
     * Convert certificate chain to string of PEM blocks.
111
     *
112
     * @return string
113
     */
114 1
    public function toPEMString(): string
115
    {
116 1
        return implode("\n",
117 1
            array_map(
118 1
                function (Certificate $cert) {
119 1
                    return $cert->toPEM()->string();
120 1
                }, $this->_certs));
121
    }
122
    
123
    /**
124
     *
125
     * @see \Countable::count()
126
     * @return int
127
     */
128 1
    public function count(): int
129
    {
130 1
        return count($this->_certs);
131
    }
132
    
133
    /**
134
     * Get iterator for certificates.
135
     *
136
     * @see \IteratorAggregate::getIterator()
137
     * @return \ArrayIterator
138
     */
139 2
    public function getIterator(): \ArrayIterator
140
    {
141 2
        return new \ArrayIterator($this->_certs);
142
    }
143
}
144