RRSIG   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 271
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 99.06%

Importance

Changes 0
Metric Value
wmc 26
lcom 1
cbo 4
dl 0
loc 271
ccs 105
cts 106
cp 0.9906
rs 10
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A getAlgorithm() 0 4 1
A getTypeCovered() 0 4 1
A setTypeCovered() 0 4 1
A setAlgorithm() 0 4 1
A getLabels() 0 4 1
A setLabels() 0 4 1
A getOriginalTtl() 0 4 1
A setOriginalTtl() 0 4 1
A getSignatureExpiration() 0 4 1
A setSignatureExpiration() 0 4 1
A getSignatureInception() 0 4 1
A setSignatureInception() 0 4 1
A getKeyTag() 0 4 1
A setKeyTag() 0 4 1
A getSignersName() 0 4 1
A setSignersName() 0 4 1
A getSignature() 0 4 1
A setSignature() 0 4 1
A toText() 0 15 1
A toWire() 0 17 1
A fromText() 0 14 1
A fromWire() 0 25 2
A makeDateTime() 0 9 3
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\Message;
17
use Badcow\DNS\Parser\Tokens;
18
19
/**
20
 * {@link https://tools.ietf.org/html/rfc4034}.
21
 */
22
class RRSIG implements RdataInterface
23
{
24 1
    use RdataTrait;
25
26
    const TYPE = 'RRSIG';
27
    const TYPE_CODE = 46;
28
    const TIME_FORMAT = 'YmdHis';
29
30
    /**
31
     *  The Type Covered field identifies the type of the RRset that is
32
     * covered by this RRSIG record. E.G. A, MX, AAAA, etc.
33
     *
34
     * @var string
35
     */
36
    private $typeCovered;
37
38
    /**
39
     * The Algorithm field identifies the public key's cryptographic
40
     * algorithm and determines the format of the Public Key field.
41
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.2}.
42
     *
43
     * @var int
44
     */
45
    private $algorithm;
46
47
    /**
48
     * The Labels field specifies the number of labels in the original RRSIG
49
     * RR owner name.
50
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.3}.
51
     *
52
     * @var int
53
     */
54
    private $labels;
55
56
    /**
57
     * The Original TTL field specifies the TTL of the covered RRset as it
58
     * appears in the authoritative zone.
59
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.4}.
60
     *
61
     * @var int
62
     */
63
    private $originalTtl;
64
65
    /**
66
     * 32-bit unsigned integer specifying the expiration date of a signature.
67
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.5}.
68
     *
69
     * @var \DateTime
70
     */
71
    private $signatureExpiration;
72
73
    /**
74
     * 32-bit unsigned integer specifying the inception date of a signature.
75
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.5}.
76
     *
77
     * @var \DateTime
78
     */
79
    private $signatureInception;
80
81
    /**
82
     * The Key Tag field contains the key tag value of the DNSKEY RR that
83
     * validates this signature, in network byte order.
84
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.6}.
85
     *
86
     * @var int
87
     */
88
    private $keyTag;
89
90
    /**
91
     * The Signer's Name field value identifies the owner name of the DNSKEY\
92
     * RR that a validator is supposed to use to validate this signature.
93
     * The Signer's Name field MUST contain the name of the zone of the
94
     * covered RRset.
95
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.7}.
96
     *
97
     * @var string
98
     */
99
    private $signersName;
100
101
    /**
102
     * The Signature field contains the cryptographic signature that covers
103
     * the RRSIG RDATA (excluding the Signature field) and the RRset
104
     * specified by the RRSIG owner name, RRSIG class, and RRSIG Type
105
     * Covered field.
106
     * {@link https://tools.ietf.org/html/rfc4034#section-3.1.8}.
107
     *
108
     * @var string
109
     */
110
    private $signature;
111
112 5
    public function getTypeCovered(): string
113
    {
114 5
        return $this->typeCovered;
115
    }
116
117 17
    public function setTypeCovered(string $typeCovered): void
118
    {
119 17
        $this->typeCovered = $typeCovered;
120 17
    }
121
122 5
    public function getAlgorithm(): int
123
    {
124 5
        return $this->algorithm;
125
    }
126
127 17
    public function setAlgorithm(int $algorithm): void
128
    {
129 17
        $this->algorithm = $algorithm;
130 17
    }
131
132 5
    public function getLabels(): int
133
    {
134 5
        return $this->labels;
135
    }
136
137 17
    public function setLabels(int $labels): void
138
    {
139 17
        $this->labels = $labels;
140 17
    }
141
142 5
    public function getOriginalTtl(): int
143
    {
144 5
        return $this->originalTtl;
145
    }
146
147 17
    public function setOriginalTtl(int $originalTtl): void
148
    {
149 17
        $this->originalTtl = $originalTtl;
150 17
    }
151
152 5
    public function getSignatureExpiration(): \DateTime
153
    {
154 5
        return $this->signatureExpiration;
155
    }
156
157 17
    public function setSignatureExpiration(\DateTime $signatureExpiration): void
158
    {
159 17
        $this->signatureExpiration = $signatureExpiration;
160 17
    }
161
162 5
    public function getSignatureInception(): \DateTime
163
    {
164 5
        return $this->signatureInception;
165
    }
166
167 17
    public function setSignatureInception(\DateTime $signatureInception): void
168
    {
169 17
        $this->signatureInception = $signatureInception;
170 17
    }
171
172 5
    public function getKeyTag(): int
173
    {
174 5
        return $this->keyTag;
175
    }
176
177 17
    public function setKeyTag(int $keyTag): void
178
    {
179 17
        $this->keyTag = $keyTag;
180 17
    }
181
182 5
    public function getSignersName(): string
183
    {
184 5
        return $this->signersName;
185
    }
186
187 17
    public function setSignersName(string $signersName): void
188
    {
189 17
        $this->signersName = $signersName;
190 17
    }
191
192 5
    public function getSignature(): string
193
    {
194 5
        return $this->signature;
195
    }
196
197 17
    public function setSignature(string $signature): void
198
    {
199 17
        $this->signature = $signature;
200 17
    }
201
202 4
    public function toText(): string
203
    {
204 4
        return sprintf(
205 4
            '%s %s %s %s %s %s %s %s %s',
206 4
            $this->typeCovered,
207 4
            $this->algorithm,
208 4
            $this->labels,
209 4
            $this->originalTtl,
210 4
            $this->signatureExpiration->format(self::TIME_FORMAT),
211 4
            $this->signatureInception->format(self::TIME_FORMAT),
212 4
            $this->keyTag,
213 4
            $this->signersName,
214 4
            base64_encode($this->signature)
215
        );
216
    }
217
218
    /**
219
     * @throws UnsupportedTypeException
220
     */
221 1
    public function toWire(): string
222
    {
223 1
        $wire = pack('nCCNNNn',
224 1
            Types::getTypeCode($this->typeCovered),
225 1
            $this->algorithm,
226 1
            $this->labels,
227 1
            $this->originalTtl,
228 1
            (int) $this->signatureExpiration->format('U'),
229 1
            (int) $this->signatureInception->format('U'),
230 1
            $this->keyTag
231
        );
232
233 1
        $wire .= Message::encodeName($this->signersName);
234 1
        $wire .= $this->signature;
235
236 1
        return $wire;
237
    }
238
239 3
    public function fromText(string $text): void
240
    {
241 3
        $rdata = explode(Tokens::SPACE, $text);
242
243 3
        $this->setTypeCovered((string) array_shift($rdata));
244 3
        $this->setAlgorithm((int) array_shift($rdata));
245 3
        $this->setLabels((int) array_shift($rdata));
246 3
        $this->setOriginalTtl((int) array_shift($rdata));
247 3
        $this->setSignatureExpiration(self::makeDateTime((string) array_shift($rdata)));
248 3
        $this->setSignatureInception(self::makeDateTime((string) array_shift($rdata)));
249 3
        $this->setKeyTag((int) array_shift($rdata));
250 3
        $this->setSignersName((string) array_shift($rdata));
251 3
        $this->setSignature(base64_decode(implode('', $rdata)));
252 3
    }
253
254
    /**
255
     * @throws UnsupportedTypeException
256
     */
257 1
    public function fromWire(string $rdata, int &$offset = 0, ?int $rdLength = null): void
258
    {
259 1
        $rdLength = $rdLength ?? strlen($rdata);
260 1
        $end = $offset + $rdLength;
261 1
        if (false === $values = unpack('n<type>/C<algorithm>/C<labels>/N<originalTtl>/N<sigExpiration>/N<sigInception>/n<keyTag>', $rdata, $offset)) {
262 1
            throw new DecodeException(static::TYPE, $rdata);
263 1
        }
264
        $offset += 18;
265 1
        $signersName = Message::decodeName($rdata, $offset);
266 1
267 1
        $sigLen = $end - $offset;
268
        $signature = substr($rdata, $offset, $sigLen);
269 1
        $offset += $sigLen;
270 1
271 1
        $this->setTypeCovered(Types::getName($values['<type>']));
272 1
        $this->setAlgorithm($values['<algorithm>']);
273 1
        $this->setLabels($values['<labels>']);
274 1
        $this->setOriginalTtl($values['<originalTtl>']);
275 1
        $this->setKeyTag($values['<keyTag>']);
276
        $this->setSignersName($signersName);
277 1
        $this->setSignature($signature);
278 1
279 1
        $this->setSignatureExpiration(self::makeDateTime((string) $values['<sigExpiration>']));
280
        $this->setSignatureInception(self::makeDateTime((string) $values['<sigInception>']));
281 4
    }
282
283 4
    private static function makeDateTime(string $timeString): \DateTime
284 4
    {
285
        $timeFormat = (14 === strlen($timeString)) ? self::TIME_FORMAT : 'U';
286
        if (false === $dateTime = \DateTime::createFromFormat($timeFormat, $timeString)) {
287
            throw new \InvalidArgumentException(sprintf('Unable to create \DateTime object from date "%s".', $timeString));
288 4
        }
289
290
        return $dateTime;
291
    }
292
}
293