Passed
Push — master ( 4c571a...c0376f )
by Thomas
02:30
created

Der::contextTag()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 1
nop 3
dl 0
loc 7
ccs 0
cts 6
cp 0
crap 6
rs 10
1
<?php
2
3
namespace MadWizard\WebAuthn\Crypto;
4
5
class Der
6
{
7 19
    private static function length(int $len): string
8
    {
9 19
        if ($len < 128) {
10 19
            return \chr($len);
11
        }
12
13 6
        $lenBytes = '';
14 6
        while ($len > 0) {
15 6
            $lenBytes = \chr($len % 256) . $lenBytes;
16 6
            $len = \intdiv($len, 256);
17
        }
18 6
        return \chr(0x80 | \strlen($lenBytes)) . $lenBytes;
19
    }
20
21 16
    public static function sequence(string $contents): string
22
    {
23 16
        return "\x30" . self::length(\strlen($contents)) . $contents;
24
    }
25
26 16
    public static function oid(string $encoded): string
27
    {
28 16
        return "\x06" . self::length(\strlen($encoded)) . $encoded;
29
    }
30
31 8
    public static function unsignedInteger(string $bytes): string
32
    {
33 8
        $len = \strlen($bytes);
34
35
        // Remove leading zero bytes
36 8
        for ($i = 0; $i < ($len - 1); $i++) {
37 8
            if (\ord($bytes[$i]) !== 0) {
38 8
                break;
39
            }
40
        }
41 8
        if ($i !== 0) {
42 1
            $bytes = \substr($bytes, $i);
43
        }
44
45
        // If most significant bit is set, prefix with another zero to prevent it being seen as negative number
46 8
        if ((\ord($bytes[0]) & 0x80) !== 0) {
47 8
            $bytes = "\x00" . $bytes;
48
        }
49
50 8
        return "\x02" . self::length(\strlen($bytes)) . $bytes;
51
    }
52
53 16
    public static function bitString(string $bytes): string
54
    {
55 16
        $len = \strlen($bytes) + 1;
56
57 16
        return "\x03" . self::length($len) . "\x00" . $bytes;
58
    }
59
60
    public static function octetString(string $bytes): string
61
    {
62
        $len = \strlen($bytes);
63
64
        return "\x04" . self::length($len) . $bytes;
65
    }
66
67
    public static function contextTag(int $tag, bool $constructed, string $content): string
68
    {
69
        return \chr(($tag & 0x1F) |   // Context specific tag number
70
            (1 << 7) |  // Context-specific flag
71
            ($constructed ? (1 << 5) : 0)) .
72
            self::length(\strlen($content)) .
73
            $content;
74
    }
75
76 6
    public static function nullValue(): string
77
    {
78 6
        return "\x05\x00";
79
    }
80
81 14
    public static function pem(string $type, string $der): string
82
    {
83 14
        return sprintf("-----BEGIN %s-----\n", strtoupper($type)) .
84 14
            chunk_split(base64_encode($der), 64, "\n") .
85 14
            sprintf("-----END %s-----\n", strtoupper($type));
86
    }
87
}
88