GnuPG::decrypt()   A
last analyzed

Complexity

Conditions 2
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 2
eloc 6
nc 3
nop 1
1
<?php
2
3
namespace CallCenter\Component\Encrypter;
4
5
use gnupg;
6
use Exception;
7
8
/**
9
 * Class to encrypt and decrypt data using gnupg.
10
 *
11
 * The intended use of this class is to encrypt data that will be decrypted with a passphrase provided by a user trough a form
12
 * in a webpage, therefore, GnuPG v 1.0 SHOULD be used in order to send the passphrase as plain text trough HTTP.
13
 * Version 2 of GnuPG DOESN'T allow to send plain text passprahse trough HTTP.
14
 *
15
 * A valid key pair MUST exists in the server, otherwise this class will throw an exception. See the docs in Confluence.
16
 *
17
 * @see http://php.net/manual/en/book.gnupg.php
18
 * @see https://www.gnupg.org/gph/en/manual/c14.html#AEN25
19
 */
20
class GnuPG
21
{
22
    /**
23
     * @var string
24
     */
25
    protected $recipient = '';
26
27
    /**
28
     * @var string
29
     */
30
    protected $passphrase = '';
31
32
    /**
33
     * @var string
34
     */
35
    protected $gnupghome = '';
36
37
    /**
38
     * @var object
39
     */
40
    protected $gnupg;
41
42
    /**
43
     * @var object
44
     */
45
    protected $logger;
46
47
    /**
48
     * Class constructor.
49
     *
50
     * @param string $recipient
51
     * @param string $passphrase
52
     * @param string $gnupghome
53
     * @param object $logger
54
     */
55
    public function __construct($recipient, $passphrase, $gnupghome, $logger)
56
    {
57
        $this->recipient = $recipient;
58
        $this->passphrase = $passphrase;
59
        $this->gnupghome = $gnupghome;
60
        $this->logger = $logger;
61
62
        $this->setGnuPGEnvVariable();
63
        $this->gnupg = new gnupg();
64
        $this->setGnuPGErrorMode();
65
    }
66
67
    /**
68
     * Encrypt data.
69
     *
70
     * @param string $data
71
     *
72
     * @throws Exception
73
     *
74
     * @return string
75
     */
76
    public function encrypt($data)
77
    {
78
        try {
79
            $this->gnupg->addencryptkey($this->recipient);
80
            if (!empty($this->passphrase)) {
81
                $this->gnupg->addsignkey($this->getFingerprint(), $this->passphrase);
82
                $chiperdata = $this->gnupg->encryptsign($data);
83
            } else {
84
                $chiperdata = $this->gnupg->encrypt($data);
85
            }
86
87
            return $chiperdata;
88
        } catch (Exception $e) {
89
            $this->logger->error($e->getMessage());
90
        }
91
    }
92
93
    /**
94
     * Decrypt data.
95
     *
96
     * @param string $data
97
     *
98
     * @throws Exception
99
     *
100
     * @return string
101
     */
102
    public function decrypt($data)
103
    {
104
        try {
105
            $this->gnupg->adddecryptkey($this->recipient, $this->passphrase);
106
107
            return $this->gnupg->decrypt($data);
108
        } catch (Exception $e) {
109
            $this->logger->error($e->getMessage());
110
        }
111
    }
112
113
    /**
114
     * Setup the GnuPG path environment variable.
115
     */
116
    private function setGnuPGEnvVariable()
117
    {
118
        putenv('GNUPGHOME='.$this->gnupghome);
119
    }
120
121
    /**
122
     * Return the fingerprint of the keyring to encrypt data.
123
     *
124
     * @todo add ckeck on fingerprint against recipient, in case of posible multiple keys in the server
125
     *
126
     * @throws Exception
127
     *
128
     * @return string
129
     */
130
    private function getFingerprint()
131
    {
132
        try {
133
            $fingerprint = '';
134
            $records = $this->gnupg->keyinfo('');
135
            foreach ($records as $record) {
136
                foreach ($record['subkeys'] as $subkey) {
137
                    if ($subkey['can_encrypt'] == 1) {
138
                        //TODO: check if email and recipient match before asign $fingerprint variable
139
                        $fingerprint = $subkey['fingerprint'];
140
                    }
141
                }
142
            }
143
144
            return $fingerprint;
145
        } catch (Exception $e) {
146
            $this->logger->error($e->getMessage());
147
        }
148
    }
149
150
    /**
151
     * Set the gnupg extension eror mode to throw an Exception in case of failure.
152
     */
153
    private function setGnuPGErrorMode()
154
    {
155
        $this->gnupg->seterrormode(gnupg::ERROR_EXCEPTION);
156
157
    }
158
}
159