Passed
Branch master (fc5382)
by Fabian
03:13
created

Certificate::generateCSR()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 62
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 27
dl 0
loc 62
ccs 0
cts 25
cp 0
rs 9.1768
c 4
b 0
f 0
cc 5
nc 8
nop 1
crap 30

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace LE_ACME2\Utilities;
4
5
use LE_ACME2\Order;
6
use LE_ACME2\Exception\OpenSSLException;
7
8
class Certificate {
9
10
    protected static $_featureOCSPMustStapleEnabled = false;
11
12
    public static function enableFeatureOCSPMustStaple() {
13
        self::$_featureOCSPMustStapleEnabled = true;
14
    }
15
16
    public static function disableFeatureOCSPMustStaple() {
17
        self::$_featureOCSPMustStapleEnabled = false;
18
    }
19
20
    /**
21
     * @param Order $order
22
     * @return string
23
     * @throws OpenSSLException
24
     */
25
    public static function generateCSR(Order $order) : string {
26
27
        $dn = [
28
            "commonName" => $order->getSubjects()[0]
29
        ];
30
31
        $san = implode(",", array_map(function ($dns) {
32
33
                return "DNS:" . $dns;
34
            }, $order->getSubjects())
35
        );
36
37
        $configFilePath = $order->getKeyDirectoryPath() . 'csr_config';
38
39
        $config = 'HOME = .
40
			RANDFILE = ' . $order->getKeyDirectoryPath() . '.rnd
41
			[ req ]
42
			default_bits = 4096
43
			default_keyfile = privkey.pem
44
			distinguished_name = req_distinguished_name
45
			req_extensions = v3_req
46
			[ req_distinguished_name ]
47
			countryName = Country Name (2 letter code)
48
			[ v3_req ]
49
			basicConstraints = CA:FALSE
50
			subjectAltName = ' . $san . '
51
			keyUsage = nonRepudiation, digitalSignature, keyEncipherment';
52
53
        if(self::$_featureOCSPMustStapleEnabled) {
54
            $config .= PHP_EOL . 'tlsfeature=status_request';
55
        }
56
57
        file_put_contents($configFilePath, $config);
58
59
        $privateKey = openssl_pkey_get_private(
60
            file_get_contents($order->getKeyDirectoryPath() . 'private.pem')
61
        );
62
63
        if($privateKey === false) {
64
            throw new OpenSSLException('openssl_pkey_get_private');
65
        }
66
67
        $csr = openssl_csr_new(
68
            $dn,
69
            $privateKey,
0 ignored issues
show
Bug introduced by
It seems like $privateKey can also be of type resource; however, parameter $private_key of openssl_csr_new() does only seem to accept OpenSSLAsymmetricKey, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
            /** @scrutinizer ignore-type */ $privateKey,
Loading history...
70
            [
71
                'config' => $configFilePath,
72
                'digest_alg' => 'sha256'
73
            ]
74
        );
75
76
        if($csr === false) {
77
            throw new OpenSSLException('openssl_csr_new');
78
        }
79
80
        if(!openssl_csr_export($csr, $csr)) {
0 ignored issues
show
Bug introduced by
$csr of type OpenSSLCertificateSigningRequest|resource is incompatible with the type string expected by parameter $output of openssl_csr_export(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
        if(!openssl_csr_export($csr, /** @scrutinizer ignore-type */ $csr)) {
Loading history...
81
            throw new OpenSSLException('openssl_csr_export');
82
        }
83
84
        unlink($configFilePath);
85
86
        return $csr;
87
    }
88
}