Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
31 / 31 |
|
100.00% |
6 / 6 |
CRAP | |
100.00% |
1 / 1 |
Box | |
100.00% |
31 / 31 |
|
100.00% |
6 / 6 |
10 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
validateNonce | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
getNonce | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
getKeyPair | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
encrypt | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
decrypt | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 |
1 | <?php declare(strict_types=1); |
2 | /* |
3 | * This file is part of Aplus Framework Crypto Library. |
4 | * |
5 | * (c) Natan Felles <natanfelles@gmail.com> |
6 | * |
7 | * For the full copyright and license information, please view the LICENSE |
8 | * file that was distributed with this source code. |
9 | */ |
10 | namespace Framework\Crypto; |
11 | |
12 | use LengthException; |
13 | use LogicException; |
14 | use SensitiveParameter; |
15 | use SodiumException; |
16 | |
17 | /** |
18 | * Class Box. |
19 | * |
20 | * @package crypto |
21 | */ |
22 | class Box |
23 | { |
24 | use BoxTrait; |
25 | |
26 | protected string $secretKey; |
27 | protected string $publicKey; |
28 | protected ?string $nonce; |
29 | |
30 | /** |
31 | * Box constructor. |
32 | * |
33 | * @param string $secretKey |
34 | * @param string $publicKey |
35 | * @param string|null $nonce |
36 | * |
37 | * @see BoxTrait::makePublicKey() |
38 | * @see BoxTrait::makeSecretKey() |
39 | * @see BoxTrait::makeNonce() |
40 | * |
41 | * @throws LengthException if nonce is set has not the required length |
42 | */ |
43 | public function __construct( |
44 | #[SensitiveParameter] string $secretKey, |
45 | #[SensitiveParameter] string $publicKey, |
46 | #[SensitiveParameter] string $nonce = null |
47 | ) { |
48 | $this->secretKey = $secretKey; |
49 | $this->publicKey = $publicKey; |
50 | if ($nonce !== null) { |
51 | $this->validateNonce($nonce); |
52 | } |
53 | $this->nonce = $nonce; |
54 | } |
55 | |
56 | /** |
57 | * Validates a nonce. |
58 | * |
59 | * @param string $nonce |
60 | * |
61 | * @throws LengthException if nonce has not the required length |
62 | */ |
63 | protected function validateNonce(#[SensitiveParameter] string $nonce) : void |
64 | { |
65 | $length = \mb_strlen($nonce, '8bit'); |
66 | if ($length !== \SODIUM_CRYPTO_BOX_NONCEBYTES) { |
67 | throw new LengthException( |
68 | 'Box nonce has not the required length (24 bytes), ' |
69 | . $length . ' given' |
70 | ); |
71 | } |
72 | } |
73 | |
74 | /** |
75 | * @param string|null $nonce |
76 | * |
77 | * @throws LengthException if nonce is set and has not the required length |
78 | * @throws LogicException if nonce param is null and nonce was not set in |
79 | * constructor |
80 | * |
81 | * @return string |
82 | */ |
83 | protected function getNonce(#[SensitiveParameter] ?string $nonce) : string |
84 | { |
85 | if ($nonce !== null) { |
86 | $this->validateNonce($nonce); |
87 | return $nonce; |
88 | } |
89 | if ($this->nonce === null) { |
90 | throw new LogicException('Nonce was not set'); |
91 | } |
92 | return $this->nonce; |
93 | } |
94 | |
95 | /** |
96 | * Gets the keypair from the secret and public keys. |
97 | * |
98 | * @throws SodiumException |
99 | * |
100 | * @return string |
101 | */ |
102 | protected function getKeyPair() : string |
103 | { |
104 | return \sodium_crypto_box_keypair_from_secretkey_and_publickey( |
105 | $this->secretKey, |
106 | $this->publicKey |
107 | ); |
108 | } |
109 | |
110 | /** |
111 | * Encrypts a box message. |
112 | * |
113 | * @param string $message |
114 | * @param string|null $nonce The message nonce or null to use the nonce set |
115 | * int the constructor |
116 | * |
117 | * @throws LengthException if nonce is set and has not the required length |
118 | * @throws LogicException if nonce param is null and nonce was not set in |
119 | * the constructor |
120 | * @throws SodiumException |
121 | * |
122 | * @return string |
123 | */ |
124 | public function encrypt( |
125 | #[SensitiveParameter] string $message, |
126 | #[SensitiveParameter] string $nonce = null |
127 | ) : string { |
128 | return \sodium_crypto_box( |
129 | $message, |
130 | $this->getNonce($nonce), |
131 | $this->getKeyPair() |
132 | ); |
133 | } |
134 | |
135 | /** |
136 | * Decrypts a box message ciphertext. |
137 | * |
138 | * @param string $ciphertext |
139 | * @param string|null $nonce The message nonce or null to use the nonce set |
140 | * int the constructor |
141 | * |
142 | * @throws LengthException if nonce is set and has not the required length |
143 | * @throws LogicException if nonce param is null and nonce was not set in |
144 | * the constructor |
145 | * @throws SodiumException |
146 | * |
147 | * @return false|string |
148 | */ |
149 | public function decrypt( |
150 | #[SensitiveParameter] string $ciphertext, |
151 | #[SensitiveParameter] string $nonce = null |
152 | ) : false | string { |
153 | return \sodium_crypto_box_open( |
154 | $ciphertext, |
155 | $this->getNonce($nonce), |
156 | $this->getKeyPair() |
157 | ); |
158 | } |
159 | } |