1 | <?php |
||
2 | /** |
||
3 | * Integration. |
||
4 | * |
||
5 | * @author Pronamic <[email protected]> |
||
6 | * @copyright 2005-2021 Pronamic |
||
7 | * @license GPL-3.0-or-later |
||
8 | * @package Pronamic\WordPress\Pay |
||
9 | */ |
||
10 | |||
11 | namespace Pronamic\WordPress\Pay\Gateways\IDealAdvancedV3; |
||
12 | |||
13 | use Pronamic\WordPress\Pay\Gateways\IDeal\AbstractIntegration; |
||
14 | |||
15 | /** |
||
16 | * Title: iDEAL Advanced v3 integration |
||
17 | * Description: |
||
18 | * Copyright: 2005-2021 Pronamic |
||
19 | * Company: Pronamic |
||
20 | * |
||
21 | * @author Remco Tolsma |
||
22 | * @version 2.1.1 |
||
23 | * @since 2.0.0 |
||
24 | */ |
||
25 | class Integration extends AbstractIntegration { |
||
26 | /** |
||
27 | * Construct iDEAL Advanced v3 integration. |
||
28 | * |
||
29 | * @param array<string, mixed> $args Arguments. |
||
30 | * @return void |
||
31 | */ |
||
32 | public function __construct( $args = array() ) { |
||
33 | $args = wp_parse_args( |
||
34 | $args, |
||
35 | array( |
||
36 | 'id' => 'ideal-advanced-v3', |
||
37 | 'name' => 'iDEAL Advanced v3', |
||
38 | 'url' => \__( 'https://www.ideal.nl/en/', 'pronamic_ideal' ), |
||
39 | 'product_url' => \__( 'https://www.ideal.nl/en/', 'pronamic_ideal' ), |
||
40 | 'manual_url' => null, |
||
41 | 'dashboard_url' => null, |
||
42 | 'provider' => null, |
||
43 | 'acquirer_url' => null, |
||
44 | 'acquirer_test_url' => null, |
||
45 | 'supports' => array( |
||
46 | 'payment_status_request', |
||
47 | ), |
||
48 | ) |
||
49 | ); |
||
50 | |||
51 | parent::__construct( $args ); |
||
52 | |||
53 | // Acquirer URL. |
||
54 | $this->acquirer_url = $args['acquirer_url']; |
||
55 | $this->acquirer_test_url = $args['acquirer_test_url']; |
||
56 | |||
57 | // Actions. |
||
58 | add_action( 'current_screen', array( $this, 'maybe_download_private_certificate' ) ); |
||
59 | add_action( 'current_screen', array( $this, 'maybe_download_private_key' ) ); |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * Get settings fields. |
||
64 | * |
||
65 | * @return array<int, array<string, callable|int|string|bool|array<int|string,int|string>>> |
||
66 | */ |
||
67 | public function get_settings_fields() { |
||
68 | $fields = parent::get_settings_fields(); |
||
69 | |||
70 | /* |
||
71 | * Private Key and Certificate |
||
72 | */ |
||
73 | |||
74 | // Private key and certificate information. |
||
75 | $fields[] = array( |
||
76 | 'section' => 'general', |
||
77 | 'title' => __( 'Private key and certificate', 'pronamic_ideal' ), |
||
78 | 'type' => 'description', |
||
79 | 'callback' => array( $this, 'field_security' ), |
||
80 | ); |
||
81 | |||
82 | // Organization. |
||
83 | $fields[] = array( |
||
84 | 'section' => 'general', |
||
85 | 'filter' => FILTER_SANITIZE_STRING, |
||
86 | 'group' => 'pk-cert', |
||
87 | 'meta_key' => '_pronamic_gateway_organization', |
||
88 | 'title' => __( 'Organization', 'pronamic_ideal' ), |
||
89 | 'type' => 'text', |
||
90 | 'tooltip' => __( 'Organization name, e.g. Pronamic', 'pronamic_ideal' ), |
||
91 | ); |
||
92 | |||
93 | // Organization Unit. |
||
94 | $fields[] = array( |
||
95 | 'section' => 'general', |
||
96 | 'filter' => FILTER_SANITIZE_STRING, |
||
97 | 'group' => 'pk-cert', |
||
98 | 'meta_key' => '_pronamic_gateway_organization_unit', |
||
99 | 'title' => __( 'Organization Unit', 'pronamic_ideal' ), |
||
100 | 'type' => 'text', |
||
101 | 'tooltip' => __( 'Organization unit, e.g. Administration', 'pronamic_ideal' ), |
||
102 | ); |
||
103 | |||
104 | // Locality. |
||
105 | $fields[] = array( |
||
106 | 'section' => 'general', |
||
107 | 'filter' => FILTER_SANITIZE_STRING, |
||
108 | 'group' => 'pk-cert', |
||
109 | 'meta_key' => '_pronamic_gateway_locality', |
||
110 | 'title' => __( 'City', 'pronamic_ideal' ), |
||
111 | 'type' => 'text', |
||
112 | 'tooltip' => __( 'City, e.g. Amsterdam', 'pronamic_ideal' ), |
||
113 | ); |
||
114 | |||
115 | // State or Province. |
||
116 | $fields[] = array( |
||
117 | 'section' => 'general', |
||
118 | 'filter' => FILTER_SANITIZE_STRING, |
||
119 | 'group' => 'pk-cert', |
||
120 | 'meta_key' => '_pronamic_gateway_state_or_province', |
||
121 | 'title' => __( 'State / province', 'pronamic_ideal' ), |
||
122 | 'type' => 'text', |
||
123 | 'tooltip' => __( 'State or province, e.g. Friesland', 'pronamic_ideal' ), |
||
124 | ); |
||
125 | |||
126 | // Country. |
||
127 | $locale = \explode( '_', \get_locale() ); |
||
128 | |||
129 | $locale = count( $locale ) > 1 ? $locale[1] : $locale[0]; |
||
130 | |||
131 | $fields[] = array( |
||
132 | 'section' => 'general', |
||
133 | 'filter' => FILTER_SANITIZE_STRING, |
||
134 | 'group' => 'pk-cert', |
||
135 | 'meta_key' => '_pronamic_gateway_country', |
||
136 | 'title' => __( 'Country', 'pronamic_ideal' ), |
||
137 | 'type' => 'text', |
||
138 | 'tooltip' => sprintf( |
||
139 | '%s %s (ISO-3166-1 alpha-2)', |
||
140 | __( '2 letter country code, e.g.', 'pronamic_ideal' ), |
||
141 | strtoupper( $locale ) |
||
142 | ), |
||
143 | 'size' => 2, |
||
144 | 'description' => sprintf( |
||
145 | '%s %s', |
||
146 | __( '2 letter country code, e.g.', 'pronamic_ideal' ), |
||
147 | strtoupper( $locale ) |
||
148 | ), |
||
149 | ); |
||
150 | |||
151 | // Email Address. |
||
152 | $fields[] = array( |
||
153 | 'section' => 'general', |
||
154 | 'filter' => FILTER_SANITIZE_STRING, |
||
155 | 'group' => 'pk-cert', |
||
156 | 'meta_key' => '_pronamic_gateway_email', |
||
157 | 'title' => __( 'E-mail address', 'pronamic_ideal' ), |
||
158 | 'tooltip' => sprintf( |
||
159 | /* translators: %s: admin email */ |
||
160 | __( 'E-mail address, e.g. %s', 'pronamic_ideal' ), |
||
161 | (string) get_option( 'admin_email' ) |
||
162 | ), |
||
163 | 'type' => 'text', |
||
164 | ); |
||
165 | |||
166 | // Number Days Valid. |
||
167 | $fields[] = array( |
||
168 | 'section' => 'general', |
||
169 | 'filter' => FILTER_SANITIZE_NUMBER_INT, |
||
170 | 'group' => 'pk-cert', |
||
171 | 'meta_key' => '_pronamic_gateway_number_days_valid', |
||
172 | 'title' => __( 'Number Days Valid', 'pronamic_ideal' ), |
||
173 | 'type' => 'text', |
||
174 | 'default' => 1825, |
||
175 | 'tooltip' => __( 'Number of days the generated certificate will be valid for, e.g. 1825 days for the maximum duration of 5 years.', 'pronamic_ideal' ), |
||
176 | ); |
||
177 | |||
178 | // Private Key Password. |
||
179 | $fields[] = array( |
||
180 | 'section' => 'general', |
||
181 | 'filter' => FILTER_SANITIZE_STRING, |
||
182 | 'group' => 'pk-cert', |
||
183 | 'meta_key' => '_pronamic_gateway_ideal_private_key_password', |
||
184 | 'title' => __( 'Private Key Password', 'pronamic_ideal' ), |
||
185 | 'type' => 'text', |
||
186 | 'classes' => array( 'regular-text', 'code' ), |
||
187 | 'default' => wp_generate_password(), |
||
188 | 'tooltip' => __( 'A random password which will be used for the generation of the private key and certificate.', 'pronamic_ideal' ), |
||
189 | ); |
||
190 | |||
191 | // Private Key. |
||
192 | $fields[] = array( |
||
193 | 'section' => 'general', |
||
194 | 'filter' => FILTER_SANITIZE_STRING, |
||
195 | 'group' => 'pk-cert', |
||
196 | 'meta_key' => '_pronamic_gateway_ideal_private_key', |
||
197 | 'title' => __( 'Private Key', 'pronamic_ideal' ), |
||
198 | 'type' => 'textarea', |
||
199 | 'callback' => array( $this, 'field_private_key' ), |
||
200 | 'classes' => array( 'code' ), |
||
201 | 'tooltip' => __( 'The private key is used for secure communication with the payment provider. If left empty, the private key will be generated using the given private key password.', 'pronamic_ideal' ), |
||
202 | ); |
||
203 | |||
204 | // Private Certificate. |
||
205 | $fields[] = array( |
||
206 | 'section' => 'general', |
||
207 | 'filter' => FILTER_SANITIZE_STRING, |
||
208 | 'group' => 'pk-cert', |
||
209 | 'meta_key' => '_pronamic_gateway_ideal_private_certificate', |
||
210 | 'title' => __( 'Private Certificate', 'pronamic_ideal' ), |
||
211 | 'type' => 'textarea', |
||
212 | 'callback' => array( $this, 'field_private_certificate' ), |
||
213 | 'classes' => array( 'code' ), |
||
214 | 'tooltip' => __( 'The certificate is used for secure communication with the payment provider. If left empty, the certificate will be generated using the private key and given organization details.', 'pronamic_ideal' ), |
||
215 | ); |
||
216 | |||
217 | // Return. |
||
218 | return $fields; |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * Field security |
||
223 | * |
||
224 | * @param array<string, mixed> $field Field. |
||
225 | * @return void |
||
226 | */ |
||
227 | public function field_security( $field ) { |
||
228 | $post_id = (int) \get_the_ID(); |
||
229 | |||
230 | $certificate = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_certificate', true ); |
||
231 | |||
232 | ?> |
||
233 | <p> |
||
234 | <?php if ( empty( $certificate ) ) : ?> |
||
235 | |||
236 | <span |
||
237 | class="dashicons dashicons-no"></span> <?php esc_html_e( 'The private key and certificate have not yet been configured.', 'pronamic_ideal' ); ?> |
||
238 | <br/> |
||
239 | |||
240 | <br/> |
||
241 | |||
242 | <?php esc_html_e( 'A private key and certificate are required for communication with the payment provider. Enter the organization details from the iDEAL account below to generate these required files.', 'pronamic_ideal' ); ?> |
||
243 | |||
244 | <?php else : ?> |
||
245 | |||
246 | <span |
||
247 | class="dashicons dashicons-yes"></span> <?php esc_html_e( 'A private key and certificate have been configured. The certificate must be uploaded to the payment provider dashboard to complete configuration.', 'pronamic_ideal' ); ?> |
||
248 | <br/> |
||
249 | |||
250 | <br/> |
||
251 | |||
252 | <?php |
||
253 | |||
254 | submit_button( |
||
255 | __( 'Download certificate', 'pronamic_ideal' ), |
||
256 | 'secondary', |
||
257 | 'download_private_certificate', |
||
258 | false |
||
259 | ); |
||
260 | |||
261 | ?> |
||
262 | |||
263 | <?php endif; ?> |
||
264 | </p> |
||
265 | <?php |
||
266 | } |
||
267 | |||
268 | /** |
||
269 | * Field private key. |
||
270 | * |
||
271 | * @param array<string, mixed> $field Field. |
||
272 | * @return void |
||
273 | */ |
||
274 | public function field_private_key( $field ) { |
||
275 | $post_id = (int) \get_the_ID(); |
||
276 | |||
277 | $private_key = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key', true ); |
||
278 | $private_key_password = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key_password', true ); |
||
279 | $number_days_valid = get_post_meta( $post_id, '_pronamic_gateway_number_days_valid', true ); |
||
280 | |||
281 | $filename = __( 'ideal.key', 'pronamic_ideal' ); |
||
282 | |||
283 | if ( ! empty( $private_key_password ) && ! empty( $number_days_valid ) ) { |
||
284 | $command = sprintf( |
||
285 | 'openssl genrsa -aes128 -out %s -passout pass:%s 2048', |
||
286 | escapeshellarg( $filename ), |
||
287 | escapeshellarg( $private_key_password ) |
||
288 | ); |
||
289 | |||
290 | ?> |
||
291 | |||
292 | <p><?php esc_html_e( 'OpenSSL command', 'pronamic_ideal' ); ?></p> |
||
293 | <input id="pronamic_ideal_openssl_command_key" name="pronamic_ideal_openssl_command_key" value="<?php echo esc_attr( $command ); ?>" type="text" class="large-text code" readonly="readonly"/> |
||
294 | |||
295 | <?php |
||
296 | } else { |
||
297 | printf( |
||
298 | '<p class="pronamic-pay-description description">%s</p>', |
||
299 | esc_html__( 'Leave empty and save the configuration to generate the private key or view the OpenSSL command.', 'pronamic_ideal' ) |
||
300 | ); |
||
301 | } |
||
302 | |||
303 | ?> |
||
304 | <p> |
||
305 | <?php |
||
306 | |||
307 | if ( ! empty( $private_key ) ) { |
||
308 | submit_button( |
||
309 | __( 'Download', 'pronamic_ideal' ), |
||
310 | 'secondary', |
||
311 | 'download_private_key', |
||
312 | false |
||
313 | ); |
||
314 | |||
315 | echo ' '; |
||
316 | } |
||
317 | |||
318 | printf( |
||
319 | '<label class="pronamic-pay-form-control-file-button button">%s <input type="file" name="%s" /></label>', |
||
320 | esc_html__( 'Upload', 'pronamic_ideal' ), |
||
321 | '_pronamic_gateway_ideal_private_key_file' |
||
322 | ); |
||
323 | |||
324 | ?> |
||
325 | </p> |
||
326 | <?php |
||
327 | } |
||
328 | |||
329 | /** |
||
330 | * Field private certificate. |
||
331 | * |
||
332 | * @param array<string, mixed> $field Field. |
||
333 | * @return void |
||
334 | */ |
||
335 | public function field_private_certificate( $field ) { |
||
336 | $post_id = (int) \get_the_ID(); |
||
337 | |||
338 | $certificate = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_certificate', true ); |
||
339 | |||
340 | $private_key_password = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key_password', true ); |
||
341 | $number_days_valid = get_post_meta( $post_id, '_pronamic_gateway_number_days_valid', true ); |
||
342 | |||
343 | $filename_key = __( 'ideal.key', 'pronamic_ideal' ); |
||
344 | $filename_cer = __( 'ideal.cer', 'pronamic_ideal' ); |
||
345 | |||
346 | // @link http://www.openssl.org/docs/apps/req.html |
||
347 | $subj_args = array( |
||
348 | 'C' => get_post_meta( $post_id, '_pronamic_gateway_country', true ), |
||
349 | 'ST' => get_post_meta( $post_id, '_pronamic_gateway_state_or_province', true ), |
||
350 | 'L' => get_post_meta( $post_id, '_pronamic_gateway_locality', true ), |
||
351 | 'O' => get_post_meta( $post_id, '_pronamic_gateway_organization', true ), |
||
352 | 'OU' => get_post_meta( $post_id, '_pronamic_gateway_organization_unit', true ), |
||
353 | 'CN' => get_post_meta( $post_id, '_pronamic_gateway_organization', true ), |
||
354 | 'emailAddress' => get_post_meta( $post_id, '_pronamic_gateway_email', true ), |
||
355 | ); |
||
356 | |||
357 | $subj_args = array_filter( $subj_args ); |
||
358 | |||
359 | $subj = ''; |
||
360 | |||
361 | foreach ( $subj_args as $type => $value ) { |
||
362 | $subj .= '/' . $type . '=' . addslashes( $value ); |
||
363 | } |
||
364 | |||
365 | if ( ! empty( $subj ) ) { |
||
366 | $command = trim( |
||
367 | sprintf( |
||
368 | 'openssl req -x509 -sha256 -new -key %s -passin pass:%s -days %s -out %s %s', |
||
369 | escapeshellarg( $filename_key ), |
||
370 | escapeshellarg( $private_key_password ), |
||
371 | escapeshellarg( $number_days_valid ), |
||
372 | escapeshellarg( $filename_cer ), |
||
373 | sprintf( '-subj %s', escapeshellarg( $subj ) ) |
||
374 | ) |
||
375 | ); |
||
376 | |||
377 | ?> |
||
378 | |||
379 | <p><?php esc_html_e( 'OpenSSL command', 'pronamic_ideal' ); ?></p> |
||
380 | <input id="pronamic_ideal_openssl_command_certificate" name="pronamic_ideal_openssl_command_certificate" value="<?php echo esc_attr( $command ); ?>" type="text" class="large-text code" readonly="readonly"/> |
||
381 | |||
382 | <?php |
||
383 | } else { |
||
384 | printf( |
||
385 | '<p class="pronamic-pay-description description">%s</p>', |
||
386 | esc_html__( 'Leave empty and save the configuration to generate the certificate or view the OpenSSL command.', 'pronamic_ideal' ) |
||
387 | ); |
||
388 | } |
||
389 | |||
390 | if ( ! empty( $certificate ) ) { |
||
391 | $fingerprint = (string) Security::get_sha_fingerprint( $certificate ); |
||
392 | $fingerprint = str_split( $fingerprint, 2 ); |
||
393 | $fingerprint = implode( ':', $fingerprint ); |
||
394 | |||
395 | echo '<dl>'; |
||
396 | |||
397 | echo '<dt>', esc_html__( 'SHA Fingerprint', 'pronamic_ideal' ), '</dt>'; |
||
398 | echo '<dd>', esc_html( $fingerprint ), '</dd>'; |
||
399 | |||
400 | $info = openssl_x509_parse( $certificate ); |
||
401 | |||
402 | if ( $info ) { |
||
0 ignored issues
–
show
|
|||
403 | $date_format = __( 'M j, Y @ G:i', 'pronamic_ideal' ); |
||
404 | |||
405 | if ( isset( $info['validFrom_time_t'] ) ) { |
||
406 | echo '<dt>', esc_html__( 'Valid From', 'pronamic_ideal' ), '</dt>'; |
||
407 | echo '<dd>', esc_html( date_i18n( $date_format, $info['validFrom_time_t'] ) ), '</dd>'; |
||
408 | } |
||
409 | |||
410 | if ( isset( $info['validTo_time_t'] ) ) { |
||
411 | echo '<dt>', esc_html__( 'Valid To', 'pronamic_ideal' ), '</dt>'; |
||
412 | echo '<dd>', esc_html( date_i18n( $date_format, $info['validTo_time_t'] ) ), '</dd>'; |
||
413 | } |
||
414 | } |
||
415 | |||
416 | echo '</dl>'; |
||
417 | } |
||
418 | |||
419 | ?> |
||
420 | <p> |
||
421 | <?php |
||
422 | |||
423 | if ( ! empty( $certificate ) ) { |
||
424 | submit_button( |
||
425 | __( 'Download', 'pronamic_ideal' ), |
||
426 | 'secondary', |
||
427 | 'download_private_certificate', |
||
428 | false |
||
429 | ); |
||
430 | |||
431 | echo ' '; |
||
432 | } |
||
433 | |||
434 | printf( |
||
435 | '<label class="pronamic-pay-form-control-file-button button">%s <input type="file" name="%s" /></label>', |
||
436 | esc_html__( 'Upload', 'pronamic_ideal' ), |
||
437 | '_pronamic_gateway_ideal_private_certificate_file' |
||
438 | ); |
||
439 | |||
440 | ?> |
||
441 | </p> |
||
442 | <?php |
||
443 | } |
||
444 | |||
445 | /** |
||
446 | * Download private certificate. |
||
447 | * |
||
448 | * @return void |
||
449 | */ |
||
450 | public function maybe_download_private_certificate() { |
||
451 | if ( ! filter_has_var( INPUT_POST, 'download_private_certificate' ) ) { |
||
452 | return; |
||
453 | } |
||
454 | |||
455 | $post_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_STRING ); |
||
456 | |||
457 | $filename = sprintf( 'ideal-private-certificate-%s.cer', $post_id ); |
||
458 | |||
459 | header( 'Content-Description: File Transfer' ); |
||
460 | header( 'Content-Disposition: attachment; filename=' . $filename ); |
||
461 | header( 'Content-Type: application/x-x509-ca-cert; charset=' . get_option( 'blog_charset' ), true ); |
||
462 | |||
463 | // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
||
464 | echo get_post_meta( $post_id, '_pronamic_gateway_ideal_private_certificate', true ); |
||
465 | |||
466 | exit; |
||
0 ignored issues
–
show
|
|||
467 | } |
||
468 | |||
469 | /** |
||
470 | * Download private key. |
||
471 | * |
||
472 | * @return void |
||
473 | */ |
||
474 | public function maybe_download_private_key() { |
||
475 | if ( filter_has_var( INPUT_POST, 'download_private_key' ) ) { |
||
476 | $post_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_STRING ); |
||
477 | |||
478 | $filename = sprintf( 'ideal-private-key-%s.key', $post_id ); |
||
479 | |||
480 | header( 'Content-Description: File Transfer' ); |
||
481 | header( 'Content-Disposition: attachment; filename=' . $filename ); |
||
482 | header( 'Content-Type: application/pgp-keys; charset=' . get_option( 'blog_charset' ), true ); |
||
483 | |||
484 | // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
||
485 | echo get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key', true ); |
||
486 | |||
487 | exit; |
||
0 ignored issues
–
show
|
|||
488 | } |
||
489 | } |
||
490 | |||
491 | /** |
||
492 | * Save post. |
||
493 | * |
||
494 | * @param int $post_id Post ID. |
||
495 | * @return void |
||
496 | */ |
||
497 | public function save_post( $post_id ) { |
||
498 | // Files. |
||
499 | $files = array( |
||
500 | '_pronamic_gateway_ideal_private_key_file' => '_pronamic_gateway_ideal_private_key', |
||
501 | '_pronamic_gateway_ideal_private_certificate_file' => '_pronamic_gateway_ideal_private_certificate', |
||
502 | ); |
||
503 | |||
504 | foreach ( $files as $name => $meta_key ) { |
||
505 | // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
||
506 | if ( isset( $_FILES[ $name ] ) && UPLOAD_ERR_OK === $_FILES[ $name ]['error'] ) { |
||
507 | // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
508 | $value = file_get_contents( $_FILES[ $name ]['tmp_name'] ); |
||
509 | |||
510 | update_post_meta( $post_id, $meta_key, $value ); |
||
511 | } |
||
512 | } |
||
513 | |||
514 | // Generate private key and certificate. |
||
515 | $private_key = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key', true ); |
||
516 | $private_key_password = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key_password', true ); |
||
517 | |||
518 | if ( empty( $private_key_password ) ) { |
||
519 | // Without private key password we can't create private key and certificate. |
||
520 | return; |
||
521 | } |
||
522 | |||
523 | if ( ! in_array( 'aes-128-cbc', openssl_get_cipher_methods(), true ) ) { |
||
524 | // Without AES-128-CBC cipher method we can't create private key and certificate. |
||
525 | return; |
||
526 | } |
||
527 | |||
528 | $args = array( |
||
529 | 'digest_alg' => 'SHA256', |
||
530 | 'private_key_bits' => 2048, |
||
531 | 'private_key_type' => \OPENSSL_KEYTYPE_RSA, |
||
532 | 'encrypt_key' => true, |
||
533 | 'subjectKeyIdentifier' => 'hash', |
||
534 | 'authorityKeyIdentifier' => 'keyid:always,issuer:always', |
||
535 | 'basicConstraints' => 'CA:true', |
||
536 | ); |
||
537 | |||
538 | // Private key. |
||
539 | $pkey = openssl_pkey_get_private( $private_key, $private_key_password ); |
||
540 | |||
541 | if ( false === $pkey ) { |
||
542 | // If we can't open the private key we will create a new private key and certificate. |
||
543 | if ( defined( 'OPENSSL_CIPHER_AES_128_CBC' ) ) { |
||
544 | $args['encrypt_key_cipher'] = \OPENSSL_CIPHER_AES_128_CBC; |
||
545 | } elseif ( defined( 'OPENSSL_CIPHER_3DES' ) ) { |
||
546 | // @link https://www.pronamic.nl/wp-content/uploads/2011/12/iDEAL_Advanced_PHP_EN_V2.2.pdf |
||
547 | $args['encrypt_key_cipher'] = \OPENSSL_CIPHER_3DES; |
||
548 | } else { |
||
549 | // Unable to create private key without cipher. |
||
550 | return; |
||
551 | } |
||
552 | |||
553 | $pkey = openssl_pkey_new( $args ); |
||
554 | |||
555 | if ( false === $pkey ) { |
||
556 | return; |
||
557 | } |
||
558 | |||
559 | // Export key. |
||
560 | $result = openssl_pkey_export( $pkey, $private_key, $private_key_password, $args ); |
||
561 | |||
562 | if ( false === $result ) { |
||
563 | return; |
||
564 | } |
||
565 | |||
566 | update_post_meta( $post_id, '_pronamic_gateway_ideal_private_key', $private_key ); |
||
567 | |||
568 | // Delete private certificate since this is no longer valid. |
||
569 | delete_post_meta( $post_id, '_pronamic_gateway_ideal_private_certificate' ); |
||
570 | } |
||
571 | |||
572 | // Certificate. |
||
573 | $private_certificate = get_post_meta( $post_id, '_pronamic_gateway_ideal_private_certificate', true ); |
||
574 | $number_days_valid = get_post_meta( $post_id, '_pronamic_gateway_number_days_valid', true ); |
||
575 | |||
576 | if ( empty( $private_certificate ) ) { |
||
577 | $required_keys = array( |
||
578 | 'countryName', |
||
579 | 'stateOrProvinceName', |
||
580 | 'localityName', |
||
581 | 'organizationName', |
||
582 | 'commonName', |
||
583 | 'emailAddress', |
||
584 | ); |
||
585 | |||
586 | $distinguished_name = array( |
||
587 | 'countryName' => get_post_meta( $post_id, '_pronamic_gateway_country', true ), |
||
588 | 'stateOrProvinceName' => get_post_meta( $post_id, '_pronamic_gateway_state_or_province', true ), |
||
589 | 'localityName' => get_post_meta( $post_id, '_pronamic_gateway_locality', true ), |
||
590 | 'organizationName' => get_post_meta( $post_id, '_pronamic_gateway_organization', true ), |
||
591 | 'organizationalUnitName' => get_post_meta( $post_id, '_pronamic_gateway_organization_unit', true ), |
||
592 | 'commonName' => get_post_meta( $post_id, '_pronamic_gateway_organization', true ), |
||
593 | 'emailAddress' => get_post_meta( $post_id, '_pronamic_gateway_email', true ), |
||
594 | ); |
||
595 | |||
596 | $distinguished_name = array_filter( $distinguished_name ); |
||
597 | |||
598 | /* |
||
599 | * Create certificate only if distinguished name contains all required elements |
||
600 | * |
||
601 | * @link http://stackoverflow.com/questions/13169588/how-to-check-if-multiple-array-keys-exists |
||
602 | */ |
||
603 | if ( count( array_intersect_key( array_flip( $required_keys ), $distinguished_name ) ) === count( $required_keys ) ) { |
||
604 | // If we can't open the private key we will create a new private key and certificate. |
||
605 | if ( defined( 'OPENSSL_CIPHER_AES_128_CBC' ) ) { |
||
606 | $args['encrypt_key_cipher'] = \OPENSSL_CIPHER_AES_128_CBC; |
||
607 | } elseif ( defined( 'OPENSSL_CIPHER_3DES' ) ) { |
||
608 | // @link https://www.pronamic.nl/wp-content/uploads/2011/12/iDEAL_Advanced_PHP_EN_V2.2.pdf |
||
609 | $args['encrypt_key_cipher'] = \OPENSSL_CIPHER_3DES; |
||
610 | } else { |
||
611 | // Unable to create private key without cipher. |
||
612 | return; |
||
613 | } |
||
614 | |||
615 | $csr = openssl_csr_new( $distinguished_name, $pkey ); |
||
616 | |||
617 | if ( false !== $csr ) { |
||
618 | $cert = openssl_csr_sign( $csr, null, $pkey, $number_days_valid, $args, time() ); |
||
619 | |||
620 | if ( false !== $cert ) { |
||
621 | openssl_x509_export( $cert, $certificate ); |
||
622 | |||
623 | update_post_meta( $post_id, '_pronamic_gateway_ideal_private_certificate', $certificate ); |
||
624 | } |
||
625 | } |
||
626 | } |
||
627 | } |
||
628 | } |
||
629 | |||
630 | /** |
||
631 | * Get config. |
||
632 | * |
||
633 | * @param int $post_id Post ID. |
||
634 | * @return Config |
||
635 | */ |
||
636 | public function get_config( $post_id ) { |
||
637 | $mode = get_post_meta( $post_id, '_pronamic_gateway_mode', true ); |
||
638 | |||
639 | $config = new Config(); |
||
640 | |||
641 | $config->payment_server_url = $this->acquirer_url; |
||
642 | |||
643 | if ( 'test' === $mode && null !== $this->acquirer_test_url ) { |
||
644 | $config->payment_server_url = $this->acquirer_test_url; |
||
645 | } |
||
646 | |||
647 | $config->set_merchant_id( get_post_meta( $post_id, '_pronamic_gateway_ideal_merchant_id', true ) ); |
||
648 | $config->set_sub_id( get_post_meta( $post_id, '_pronamic_gateway_ideal_sub_id', true ) ); |
||
649 | $config->set_purchase_id( get_post_meta( $post_id, '_pronamic_gateway_ideal_purchase_id', true ) ); |
||
650 | |||
651 | $config->set_private_key( get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key', true ) ); |
||
652 | $config->set_private_key_password( get_post_meta( $post_id, '_pronamic_gateway_ideal_private_key_password', true ) ); |
||
653 | $config->set_private_certificate( get_post_meta( $post_id, '_pronamic_gateway_ideal_private_certificate', true ) ); |
||
654 | |||
655 | return $config; |
||
656 | } |
||
657 | |||
658 | /** |
||
659 | * Get gateway. |
||
660 | * |
||
661 | * @param int $post_id Post ID. |
||
662 | * @return Gateway |
||
663 | */ |
||
664 | public function get_gateway( $post_id ) { |
||
665 | return new Gateway( $this->get_config( $post_id ) ); |
||
666 | } |
||
667 | } |
||
668 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.