TrustStoreLoaderTest::testLoadFromCaStore()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Bip70\Test\X509;
6
7
use Bip70\Exception\Bip70Exception;
8
use Bip70\X509\Exception\TrustStoreException;
9
use Bip70\X509\TrustStoreLoader;
10
use Composer\CaBundle\CaBundle;
11
use PHPUnit\Framework\TestCase;
12
use Sop\CryptoEncoding\PEMBundle;
13
use X509\Certificate\Certificate;
14
use X509\Certificate\CertificateBundle;
15
16
class TrustStoreLoaderTest extends TestCase
17
{
18
    public function testLoadFromCaStore()
19
    {
20
        $caFile = CaBundle::getSystemCaRootBundlePath();
21
22
        $this->assertFileExists($caFile);
23
24
        return $caFile === CaBundle::getBundledCaBundlePath();
25
    }
26
27
    /**
28
     * @return array
29
     */
30
    public function getFromFileFixtures(): array
31
    {
32
        return [
33
            [CaBundle::getSystemCaRootBundlePath(), [TrustStoreLoader::class, 'fromSystem']],
34
            [CaBundle::getBundledCaBundlePath(), [TrustStoreLoader::class, 'fromComposerBundle']],
35
        ];
36
    }
37
38
    /**
39
     * @dataProvider getFromFileFixtures
40
     * @param string $path
41
     */
42
    public function testLoadFromFile(string $path)
43
    {
44
        $systemStore = TrustStoreLoader::fromFile($path);
45
        $this->assertGreaterThan(0, count($systemStore));
46
47
        $bundle = PEMBundle::fromFile($path);
48
        $certs = [];
49
        foreach ($bundle->getIterator() as $it) {
50
            try {
51
                $cert = Certificate::fromPEM($it);
52
                $certs[] = $cert;
53
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
54
            }
55
        }
56
57
        $cas = new CertificateBundle(...$certs);
58
        foreach ($cas->getIterator() as $ca) {
59
            $this->assertTrue($systemStore->contains($ca));
60
        }
61
    }
62
63
    /**
64
     * @dataProvider getFromFileFixtures
65
     * @param string $path
66
     * @param callable $fxn
67
     */
68
    public function testLoadFromComposerBundle($path, callable $fxn)
69
    {
70
        // this should always work..
71
        $composerBundle = call_user_func($fxn);
72
        $this->assertGreaterThan(0, count($composerBundle));
73
74
        $pems = PEMBundle::fromFile($path);
75
        $certs = [];
76
        foreach ($pems as $pem) {
77
            try {
78
                $cert = Certificate::fromPEM($pem);
79
                $certs[] = $cert;
80
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
81
            }
82
        }
83
84
        $cas = new CertificateBundle(...$certs);
85
        foreach ($cas->getIterator() as $ca) {
86
            $this->assertTrue($composerBundle->contains($ca));
87
        }
88
    }
89
90
    public function testDisablingFallbackToComposer()
91
    {
92
        $envVar = "SSL_CERT_FILE";
93
94
        // unset caPath variable first
95
        $refObject   = new \ReflectionObject(new CaBundle());
96
        $refProperty = $refObject->getProperty('caPath');
97
        $refProperty->setAccessible(true);
98
        $refProperty->setValue(null, null);
99
100
        putenv("{$envVar}=" . CaBundle::getBundledCaBundlePath());
101
102
        $this->expectException(TrustStoreException::class);
103
        $this->expectExceptionMessage("Fallback to composer ca-bundle is disabled - you should install the ca-certificates package");
104
105
        try {
106
            TrustStoreLoader::fromSystem(false);
107
        } catch (\Exception $e) {
108
            $refObject   = new \ReflectionObject(new CaBundle());
109
            $refProperty = $refObject->getProperty('caPath');
110
            $refProperty->setAccessible(true);
111
            $refProperty->setValue(null, null);
112
113
            putenv($envVar."=");
114
115
            throw $e;
116
        }
117
    }
118
119
    public function testHandlingDirectoryInFromSystem()
120
    {
121
        $envVar = "SSL_CERT_DIR";
122
123
        $systemPath = CaBundle::getSystemCaRootBundlePath();
124
125
        // unset caPath variable first
126
        $refObject   = new \ReflectionObject(new CaBundle());
127
        $refProperty = $refObject->getProperty('caPath');
128
        $refProperty->setAccessible(true);
129
        $refProperty->setValue(null, null);
130
131
        $path = implode("/", array_slice(explode("/", $systemPath), 0, -1));
132
133
        putenv("{$envVar}=" . $path);
134
135
        $trustStore = TrustStoreLoader::fromSystem();
136
        $this->assertGreaterThan(0, $trustStore->count());
137
138
        putenv("{$envVar}=");
139
    }
140
141
    public function testFromDirectoryRequiresADirectory()
142
    {
143
        $this->expectExceptionMessage("Invalid path passed to fromDirectory, is not a directory");
144
        $this->expectException(TrustStoreException::class);
145
146
        TrustStoreLoader::fromDirectory("/some/invalid/path");
147
    }
148
149
    public function testDirectoryMustHavePems()
150
    {
151
        $tmpDir = __DIR__ . "/../../../" . bin2hex(random_bytes(4));
152
        mkdir($tmpDir);
153
154
        $this->expectExceptionMessage("No PEM files in directory");
155
        $this->expectException(Bip70Exception::class);
156
157
        try {
158
            TrustStoreLoader::fromDirectory($tmpDir);
159
        } catch (\Exception $e) {
160
            rmdir($tmpDir);
161
            throw $e;
162
        }
163
    }
164
165
    public function testLoadFromDirectory()
166
    {
167
        // unset caPath variable first
168
        $refObject   = new \ReflectionObject(new CaBundle());
169
        $refProperty = $refObject->getProperty('caPath');
170
        $refProperty->setAccessible(true);
171
        $refProperty->setValue(null, null);
172
173
        $systemPath = CaBundle::getSystemCaRootBundlePath();
174
175
        // We expect ca-certificates to be installed
176
        $this->assertFalse(CaBundle::getBundledCaBundlePath() === $systemPath);
177
178
        $path = implode("/", array_slice(explode("/", $systemPath), 0, -1));
179
        $store = TrustStoreLoader::fromDirectory($path);
180
181
        $this->assertGreaterThan(0, $store->count());
182
    }
183
}
184