Completed
Push — master ( 51beac...801282 )
by Sam
03:19
created

DS::calculateDigest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
ccs 3
cts 3
cp 1
crap 2
rs 10
c 0
b 0
f 0
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
use InvalidArgumentException;
19
20
class DS implements RdataInterface
21 1
{
22
    use RdataTrait;
23
24
    const TYPE = 'DS';
25
    const TYPE_CODE = 43;
26
    const DIGEST_SHA1 = 1;
27
28
    /**
29
     * @var int
30
     */
31
    private $keyTag;
32
33
    /**
34
     * The Algorithm field lists the algorithm number of the DNSKEY RR
35
     * referred to by the DS record.
36
     * {@link https://tools.ietf.org/html/rfc4034#section-5.1.2}.
37
     *
38
     * @var int
39
     */
40
    private $algorithm;
41
42
    /**
43
     * @var int
44
     */
45
    private $digestType = self::DIGEST_SHA1;
46
47
    /**
48
     * @var string
49
     */
50
    private $digest;
51 4
52
    public function getKeyTag(): int
53 4
    {
54
        return $this->keyTag;
55
    }
56 14
57
    public function setKeyTag(int $keyTag): void
58 14
    {
59 14
        $this->keyTag = $keyTag;
60
    }
61 4
62
    public function getAlgorithm(): int
63 4
    {
64
        return $this->algorithm;
65
    }
66 14
67
    public function setAlgorithm(int $algorithm): void
68 14
    {
69 14
        $this->algorithm = $algorithm;
70
    }
71 4
72
    public function getDigestType(): int
73 4
    {
74
        return $this->digestType;
75
    }
76 14
77
    public function setDigestType(int $digestType): void
78 14
    {
79 14
        $this->digestType = $digestType;
80
    }
81
82
    /**
83
     * @return string the digest in its binary representation
84 4
     */
85
    public function getDigest(): string
86 4
    {
87
        return $this->digest;
88
    }
89
90
    /**
91
     * @param string $digest the digest in its binary representation
92 14
     */
93
    public function setDigest(string $digest): void
94 14
    {
95 14
        $this->digest = $digest;
96
    }
97
98
    /**
99
     * Calculates the digest by concatenating the canonical form of the fully qualified owner name of the DNSKEY RR with
100 2
     * the DNSKEY RDATA, and then applying the digest algorithm.
101
     *
102 2
     * @param string $owner  canonical form of the fully qualified owner name of the DNSKEY RR
103 2
     * @param DNSKEY $dnskey Owner's DNSKEY
104 2
     */
105 2
    public function calculateDigest(string $owner, DNSKEY $dnskey): void
106 2
    {
107 2
        if (static::DIGEST_SHA1 !== $this->digestType) {
108
            throw new InvalidArgumentException('Can only calculate SHA-1 digests.');
109
        }
110
111
        $this->digest = sha1(Message::encodeName(strtolower($owner)).$dnskey->toWire(), true);
112
    }
113
114 4
    /**
115
     * {@inheritdoc}
116 4
     */
117
    public function toText(): string
118
    {
119
        return sprintf(
120
            '%s %s %s %s',
121
            $this->keyTag,
122 4
            $this->algorithm,
123
            $this->digestType,
124 4
            strtoupper(bin2hex($this->digest))
125 4
        );
126 4
    }
127 4
128 4
    /**
129
     * {@inheritdoc}
130
     */
131 4
    public function toWire(): string
132 4
    {
133
        return pack('nCC', $this->keyTag, $this->algorithm, $this->digestType).$this->digest;
134
    }
135
136
    /**
137 4
     * {@inheritdoc}
138
     */
139 4
    public function fromText(string $text): void
140
    {
141 4
        $rdata = explode(Tokens::SPACE, $text);
142 4
        $this->setKeyTag((int) array_shift($rdata));
143
        $this->setAlgorithm((int) array_shift($rdata));
144 4
        $this->setDigestType((int) array_shift($rdata));
145 4
        if (false === $digest = hex2bin((string) array_shift($rdata))) {
146 4
            throw new InvalidArgumentException(sprintf('The digest is not a valid hexadecimal string.'));
147 4
        }
148
        $this->setDigest($digest);
149 4
    }
150 4
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function fromWire(string $rdata, int &$offset = 0, ?int $rdLength = null): void
155
    {
156
        $digestLen = ($rdLength ?? strlen($rdata)) - 4;
157
158
        $integers = unpack('ntag/Calgorithm/Cdtype', $rdata, $offset);
159
        $offset += 4;
160
161
        $this->setKeyTag($integers['tag']);
162
        $this->setAlgorithm($integers['algorithm']);
163
        $this->setDigestType($integers['dtype']);
164
        $this->setDigest(substr($rdata, $offset, $digestLen));
165
166
        $offset += $digestLen;
167
    }
168
}
169