Completed
Branch master (48aedc)
by thomas
03:23 queued 02:08
created

TrustStoreLoader   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 96.77%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 1
dl 0
loc 98
ccs 30
cts 31
cp 0.9677
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A fromFile() 0 18 4
A fromSystem() 0 14 4
A fromComposerBundle() 0 4 1
B fromDirectory() 0 22 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Bip70\X509;
6
7
use Bip70\Exception\Bip70Exception;
8
use Composer\CaBundle\CaBundle;
9
use Sop\CryptoEncoding\PEM;
10
use Sop\CryptoEncoding\PEMBundle;
11
use X509\Certificate\Certificate;
12
use X509\Certificate\CertificateBundle;
13
14
class TrustStoreLoader
15
{
16
    /**
17
     * Loads the currently installed ca-certificates file.
18
     * The approach taken by composer/ca-bundle is to attempt
19
     * to load certificates if openssl-like envvars and
20
     * config values are set.
21
     *
22
     * If $allowFallback is false, and the bundled composer
23
     * ca file is returned, an exception will be thrown.
24
     *
25
     * @see CaBundle::getSystemCaRootBundlePath()
26
     * @param bool $allowFallback
27
     * @return CertificateBundle
28
     */
29 9
    public static function fromSystem(bool $allowFallback = true): CertificateBundle
30
    {
31 9
        $rootBundlePath = CaBundle::getSystemCaRootBundlePath();
32
33 9
        if (!$allowFallback && CaBundle::getBundledCaBundlePath() === $rootBundlePath) {
34 1
            throw new \RuntimeException("Fallback to composer ca-bundle is disabled - you should install the ca-certificates package");
35
        }
36
37 8
        if (is_dir($rootBundlePath)) {
38 1
            return self::fromDirectory($rootBundlePath);
39
        } else {
40 7
            return self::fromFile($rootBundlePath);
41
        }
42
    }
43
44
    /**
45
     * Loads a trust store completely controlled by what is
46
     * included in the `composer/ca-bundle` package.
47
     * @return CertificateBundle
48
     */
49 1
    public static function fromComposerBundle(): CertificateBundle
50
    {
51 1
        return self::fromFile(CaBundle::getBundledCaBundlePath());
52
    }
53
54
    /**
55
     * Load a trust store from a pem bundle file (can contain
56
     * multiple certificates)
57
     *
58
     * @param string $file
59
     * @return CertificateBundle
60
     * @throws Bip70Exception
61
     */
62 10
    public static function fromFile(string $file): CertificateBundle
63
    {
64 10
        $pemBundle = PEMBundle::fromFile($file);
65 10
        $certificates = [];
66 10
        foreach ($pemBundle as $pem) {
67
            try {
68 10
                $certificate = Certificate::fromPEM($pem);
69 10
                $certificates[] = $certificate;
70 10
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
71
            }
72
        }
73
74 10
        if (count($certificates) < 1) {
75
            throw new Bip70Exception("No certificates in file");
76
        }
77
78 10
        return new CertificateBundle(...$certificates);
79
    }
80
81
    /**
82
     * Load a trust store from a pem bundle file (can contain
83
     * multiple certificates)
84
     *
85
     * @param string $dir
86
     * @return CertificateBundle
87
     * @throws Bip70Exception
88
     */
89 4
    public static function fromDirectory(string $dir): CertificateBundle
90
    {
91 4
        if (!is_dir($dir)) {
92 1
            throw new \RuntimeException("Invalid path passed to fromDirectory, is not a directory");
93
        }
94
95 3
        $certificates = [];
96 3
        foreach (glob("$dir/*.pem") as $pemFile) {
97
            try {
98 2
                $pem = PEM::fromFile($pemFile);
99 2
                $certificate = Certificate::fromPEM($pem);
100 2
                $certificates[] = $certificate;
101 2
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
102
            }
103
        }
104
105 3
        if (count($certificates) < 1) {
106 1
            throw new Bip70Exception("No PEM files in directory");
107
        }
108
109 2
        return new CertificateBundle(...$certificates);
110
    }
111
}
112