PrivateKey   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 52
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 13
c 1
b 0
f 0
dl 0
loc 52
rs 10
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A fromFile() 0 21 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\Key;
6
7
use SimpleSAML\Assert\Assert;
8
use SimpleSAML\XMLSecurity\CryptoEncoding\PEM;
9
use SimpleSAML\XMLSecurity\Exception\OpenSSLException;
10
11
use function openssl_pkey_export;
12
use function openssl_pkey_get_private;
13
use function preg_filter;
14
use function preg_match;
15
16
/**
17
 * A class modeling private keys for their use in asymmetric algorithms.
18
 *
19
 * @package simplesamlphp/xml-security
20
 */
21
class PrivateKey extends AsymmetricKey
22
{
23
    /**
24
     * Create a new private key from the PEM-encoded key material.
25
     *
26
     * @param \SimpleSAML\XMLSecurity\CryptoEncoding\PEM $key The PEM-encoded key material.
27
     */
28
    final public function __construct(
29
        #[\SensitiveParameter]
30
        PEM $key,
31
    ) {
32
        Assert::oneOf(
33
            $key->type(),
34
            [PEM::TYPE_PRIVATE_KEY, PEM::TYPE_RSA_PRIVATE_KEY],
35
            "PEM structure has the wrong type %s.",
36
        );
37
38
        parent::__construct($key);
39
    }
40
41
42
    /**
43
     * Get a new private key from a file.
44
     *
45
     * @param string $file The file where the PEM-encoded private key is stored.
46
     * @param string $passphrase An optional passphrase used to decrypt the given key material.
47
     *
48
     * @return static A new private key.
49
     *
50
     * @throws \SimpleSAML\XMLSecurity\Exception\InvalidArgumentException If the file cannot be read.
51
     */
52
    public static function fromFile(
53
        string $file,
54
        #[\SensitiveParameter]
55
        string $passphrase = '',
56
    ): static {
57
        if (preg_match(PEM::PEM_REGEX, $file) !== 1) {
58
            // Not a PEM-encoded key. Must be a file
59
            if (preg_match('/^(file:\/\/)/Di', $file) !== 1) {
60
                $file = preg_filter('/^/', 'file://', $file);
61
            }
62
        }
63
64
        if (($key = openssl_pkey_get_private($file, $passphrase)) === false) {
65
            throw new OpenSSLException('Failed to read key');
66
        }
67
68
        if (openssl_pkey_export($key, $decrypted) === false) {
69
            throw new OpenSSLException('Failed to export key');
70
        }
71
72
        return new static(PEM::fromString($decrypted));
73
    }
74
}
75