Passed
Branch master (8940db)
by Sam
02:38
created

RRSIG::output()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 12
cts 12
cp 1
rs 9.7666
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1

1 Method

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