OpenSsl::openSslKeyToString()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Rogierw\RwAcme\Support;
4
5
use OpenSSLAsymmetricKey;
6
use Rogierw\RwAcme\Exceptions\LetsEncryptClientException;
7
8
class OpenSsl
9
{
10
    public static function generatePrivateKey(int $key_type = OPENSSL_KEYTYPE_RSA): OpenSSLAsymmetricKey
11
    {
12
        return match ($key_type) {
13
            OPENSSL_KEYTYPE_RSA => openssl_pkey_new([
14
                'private_key_type' => OPENSSL_KEYTYPE_RSA,
15
                'private_key_bits' => 2048,
16
                'digest_alg' => 'sha256',
17
            ]),
18
            OPENSSL_KEYTYPE_EC => openssl_pkey_new([
19
                'private_key_type' => OPENSSL_KEYTYPE_EC,
20
                'private_key_bits' => 2048,
21
                'curve_name' => 'prime256v1',
22
            ]),
23
            default => throw new LetsEncryptClientException('Invalid keytype'),
24
        };
25
    }
26
27
    public static function openSslKeyToString(OpenSSLAsymmetricKey $key): string
28
    {
29
        if (!openssl_pkey_export($key, $output)) {
30
            throw new LetsEncryptClientException('Exporting SSL key failed.');
31
        }
32
33
        return trim($output);
34
    }
35
36
    public static function generateCsr(array $domains, OpenSSLAsymmetricKey $privateKey): string
37
    {
38
        $dn = ['commonName' => $domains[0]];
39
40
        $san = implode(',', array_map(function ($dns) {
41
            return 'DNS:' . $dns;
42
        }, $domains));
43
44
        $tempFile = tmpfile();
45
46
        fwrite(
47
            $tempFile,
48
            'HOME = .
49
			RANDFILE = $ENV::HOME/.rnd
50
			[ req ]
51
			default_bits = 4096
52
			default_keyfile = privkey.pem
53
			distinguished_name = req_distinguished_name
54
			req_extensions = v3_req
55
			[ req_distinguished_name ]
56
			countryName = Country Name (2 letter code)
57
			[ v3_req ]
58
			basicConstraints = CA:FALSE
59
			subjectAltName = ' . $san . '
60
			keyUsage = nonRepudiation, digitalSignature, keyEncipherment'
61
        );
62
63
        $csr = openssl_csr_new($dn, $privateKey, [
64
            'digest_alg' => 'sha256',
65
            'config' => stream_get_meta_data($tempFile)['uri'],
66
        ]);
67
68
        fclose($tempFile);
69
70
        if (!openssl_csr_export($csr, $out)) {
71
            throw new LetsEncryptClientException('Exporting CSR failed.');
72
        }
73
74
        return trim($out);
75
    }
76
}
77