CERT   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 3
dl 0
loc 184
ccs 58
cts 58
cp 1
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getCertificateType() 0 4 1
A setCertificateType() 0 10 3
A getKeyTag() 0 4 1
A setKeyTag() 0 4 1
A getAlgorithm() 0 4 1
A setAlgorithm() 0 10 3
A setCertificate() 0 4 1
A getCertificate() 0 4 1
A toText() 0 7 3
A toWire() 0 4 1
A fromText() 0 8 1
A fromWire() 0 14 2
A getKeyTypeValue() 0 8 2
A getKeyTypeMnemonic() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Badcow DNS Library.
7
 *
8
 * (c) Samuel Williams <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Badcow\DNS\Rdata;
15
16
use Badcow\DNS\Algorithms;
17
use Badcow\DNS\Parser\Tokens;
18
use InvalidArgumentException;
19
20
/*
21
 * {@link https://tools.ietf.org/html/rfc4398#section-2.1}.
22
 */
23
class CERT implements RdataInterface
24
{
25 1
    use RdataTrait;
26
27
    const TYPE = 'CERT';
28
    const TYPE_CODE = 37;
29
30
    const KEY_TYPE_PKIX = 1;
31
    const KEY_TYPE_SPKI = 2;
32
    const KEY_TYPE_PGP = 3;
33
    const KEY_TYPE_IPKIX = 4;
34
    const KEY_TYPE_ISPKI = 5;
35
    const KEY_TYPE_IPGP = 6;
36
    const KEY_TYPE_ACPKIX = 7;
37
    const KEY_TYPE_IACPKIX = 8;
38
    const KEY_TYPE_URI = 253;
39
    const KEY_TYPE_OID = 254;
40
41
    const MNEMONICS = [
42
        self::KEY_TYPE_PKIX => 'PKIX',
43
        self::KEY_TYPE_SPKI => 'SPKI',
44
        self::KEY_TYPE_PGP => 'PGP',
45
        self::KEY_TYPE_IPKIX => 'IPKIX',
46
        self::KEY_TYPE_ISPKI => 'ISPKI',
47
        self::KEY_TYPE_IPGP => 'IPGP',
48
        self::KEY_TYPE_ACPKIX => 'ACPKIX',
49
        self::KEY_TYPE_IACPKIX => 'IACPKIX',
50
        self::KEY_TYPE_URI => 'URI',
51
        self::KEY_TYPE_OID => 'OID',
52
    ];
53
54
    /**
55
     * @var int
56
     */
57
    private $certificateType;
58
59
    /**
60
     * @var int
61
     */
62
    private $keyTag;
63
64
    /**
65
     * @var int
66
     */
67
    private $algorithm;
68
69
    /**
70
     * @var string
71
     */
72
    private $certificate;
73
74 1
    public function getCertificateType(): int
75
    {
76 1
        return $this->certificateType;
77
    }
78
79
    /**
80
     * @param int|string $certificateType
81
     *
82
     * @throws InvalidArgumentException
83
     */
84 4
    public function setCertificateType($certificateType): void
85
    {
86 4
        if (is_int($certificateType) || 1 === preg_match('/^\d+$/', $certificateType)) {
87 1
            $this->certificateType = (int) $certificateType;
88
89 1
            return;
90
        }
91
92 4
        $this->certificateType = self::getKeyTypeValue((string) $certificateType);
93 4
    }
94
95 1
    public function getKeyTag(): int
96
    {
97 1
        return $this->keyTag;
98
    }
99
100 4
    public function setKeyTag(int $keyTag): void
101
    {
102 4
        $this->keyTag = $keyTag;
103 4
    }
104
105 1
    public function getAlgorithm(): int
106
    {
107 1
        return $this->algorithm;
108
    }
109
110
    /**
111
     * @param string|int $algorithm
112
     *
113
     * @throws InvalidArgumentException
114
     */
115 4
    public function setAlgorithm($algorithm): void
116
    {
117 4
        if (is_int($algorithm) || 1 === preg_match('/^\d+$/', $algorithm)) {
118 4
            $this->algorithm = (int) $algorithm;
119
120 4
            return;
121
        }
122
123 1
        $this->algorithm = Algorithms::getAlgorithmValue((string) $algorithm);
124 1
    }
125
126
    /**
127
     * @param string $certificate Base64 encoded string
128
     *
129
     * @throws InvalidArgumentException
130
     */
131 4
    public function setCertificate(string $certificate): void
132
    {
133 4
        $this->certificate = $certificate;
134 4
    }
135
136
    /**
137
     * @return string Base64 encoded string
138
     */
139 1
    public function getCertificate(): string
140
    {
141 1
        return $this->certificate;
142
    }
143
144 1
    public function toText(): string
145
    {
146 1
        $type = (array_key_exists($this->certificateType, self::MNEMONICS)) ? self::MNEMONICS[$this->certificateType] : (string) $this->certificateType;
147 1
        $algorithm = (array_key_exists($this->algorithm, Algorithms::MNEMONICS)) ? Algorithms::MNEMONICS[$this->algorithm] : (string) $this->algorithm;
148
149 1
        return sprintf('%s %s %s %s', $type, (string) $this->keyTag, $algorithm, base64_encode($this->certificate));
150
    }
151
152 1
    public function toWire(): string
153
    {
154 1
        return pack('nnC', $this->certificateType, $this->keyTag, $this->algorithm).$this->certificate;
155
    }
156
157 1
    public function fromText(string $text): void
158
    {
159 1
        $rdata = explode(Tokens::SPACE, $text);
160 1
        $this->setCertificateType((string) array_shift($rdata));
161 1
        $this->setKeyTag((int) array_shift($rdata));
162 1
        $this->setAlgorithm((string) array_shift($rdata));
163 1
        $this->setCertificate(base64_decode(implode('', $rdata)));
164 1
    }
165
166 1
    public function fromWire(string $rdata, int &$offset = 0, ?int $rdLength = null): void
167
    {
168 1
        if (false === $integers = unpack('ntype/nkeyTag/Calgorithm', $rdata, $offset)) {
169 1
            throw new DecodeException(static::TYPE, $rdata);
170 1
        }
171 1
        $offset += 5;
172 1
        $this->setCertificateType((int) $integers['type']);
173
        $this->setKeyTag((int) $integers['keyTag']);
174 1
        $this->setAlgorithm((int) $integers['algorithm']);
175 1
176 1
        $certLen = ($rdLength ?? strlen($rdata)) - 5;
177 1
        $this->setCertificate(substr($rdata, $offset, $certLen));
178
        $offset += $certLen;
179
    }
180
181
    /**
182 5
     * @throws InvalidArgumentException
183
     */
184 5
    public static function getKeyTypeValue(string $keyTypeMnemonic): int
185 1
    {
186
        if (false === $keyTypeValue = array_search($keyTypeMnemonic, self::MNEMONICS, true)) {
187
            throw new InvalidArgumentException(sprintf('"%s" is not a valid key type mnemonic.', $keyTypeMnemonic));
188 5
        }
189
190
        return (int) $keyTypeValue;
191
    }
192
193
    /**
194
     * Get the associated mnemonic of a key type.
195
     *
196 1
     * @throws InvalidArgumentException
197
     */
198 1
    public static function getKeyTypeMnemonic(int $keyTypeValue): string
199 1
    {
200
        if (!array_key_exists($keyTypeValue, self::MNEMONICS)) {
201
            throw new InvalidArgumentException(sprintf('"%d" is not a valid key type.', $keyTypeValue));
202 1
        }
203
204
        return self::MNEMONICS[$keyTypeValue];
205
    }
206
}
207