1--TEST-- 2openssl_error_string() tests 3--SKIPIF-- 4<?php if (!extension_loaded("openssl")) print "skip"; ?> 5--FILE-- 6<?php 7// helper function to check openssl errors 8function expect_openssl_errors($name, $expected_error_codes) { 9 $expected_errors = array_fill_keys($expected_error_codes, false); 10 $all_errors = array(); 11 while (($error_string = openssl_error_string()) !== false) { 12 if (preg_match(",.+:([0-9A-F]+):.+,", $error_string, $m) > 0) { 13 $error_code = $m[1]; 14 if (isset($expected_errors[$error_code])) { 15 $expected_errors[$error_code] = true; 16 } 17 $all_errors[$error_code] = $error_string; 18 } else { 19 $all_errors[] = $error_string; 20 } 21 } 22 23 $fail = false; 24 foreach ($expected_errors as $error_code => $error_code_found) { 25 if (!$error_code_found) { 26 $fail = true; 27 echo "$name: no error code $error_code\n"; 28 } 29 } 30 31 if (!$fail) { 32 echo "$name: ok\n"; 33 } else { 34 echo "$name: uncaught errors\n"; 35 foreach ($all_errors as $code => $str) { 36 if (!isset($expected_errors[$code]) || !$expected_errors[$code]) { 37 echo "\t", $code, ": ", $str, "\n"; 38 } 39 } 40 } 41} 42 43// helper for debugging errors 44function dump_openssl_errors($name) { 45 echo "\n$name\n"; 46 while (($error_string = openssl_error_string()) !== false) { 47 var_dump($error_string); 48 } 49} 50 51// common output file 52$output_file = __DIR__ . "/openssl_error_string_basic_output.tmp"; 53// invalid file for read is something that does not exist in current directory 54$invalid_file_for_read = __DIR__ . "/invalid_file_for_read_operation.txt"; 55// invalid file for is the test dir as writing file to existing dir should always fail 56$invalid_file_for_write = __DIR__; 57// crt file 58$crt_file = "file://" . __DIR__ . "/cert.crt"; 59// csr file 60$csr_file = "file://" . __DIR__ . "/cert.csr"; 61// public key file 62$public_key_file = "file://" .__DIR__ . "/public.key"; 63// private key file 64$private_key_file = "file://" .__DIR__ . "/private_rsa_1024.key"; 65// private key file with password (password is 'php') 66$private_key_file_with_pass = "file://" .__DIR__ . "/private_rsa_2048_pass_php.key"; 67 68// ENCRYPTION 69$data = "test"; 70$method = "AES-128-ECB"; 71$enc_key = str_repeat('x', 40); 72// error because password is longer then key length and 73// EVP_CIPHER_CTX_set_key_length fails for AES 74openssl_encrypt($data, $method, $enc_key); 75$enc_error = openssl_error_string(); 76var_dump($enc_error); 77// make sure that error is cleared now 78var_dump(openssl_error_string()); 79// internally OpenSSL ERR won't save more than 15 (16 - 1) errors so lets test it 80for ($i = 0; $i < 20; $i++) { 81 openssl_encrypt($data, $method, $enc_key); 82} 83$error_queue_size = 0; 84while (($enc_error_new = openssl_error_string()) !== false) { 85 if ($enc_error_new !== $enc_error) { 86 echo "The new encoding error doesn't match the expected one\n"; 87 } 88 ++$error_queue_size; 89} 90var_dump($error_queue_size); 91echo "\n"; 92 93$is_111 = OPENSSL_VERSION_NUMBER >= 0x10101000; 94$err_pem_no_start_line = $is_111 ? '0909006C': '0906D06C'; 95 96// PKEY 97echo "PKEY errors\n"; 98// file for pkey (file:///) fails when opennig (BIO_new_file) 99@openssl_pkey_export_to_file("file://" . $invalid_file_for_read, $output_file); 100expect_openssl_errors('openssl_pkey_export_to_file opening', ['02001002', '2006D080']); 101// file or private pkey is not correct PEM - failing PEM_read_bio_PrivateKey 102@openssl_pkey_export_to_file($csr_file, $output_file); 103expect_openssl_errors('openssl_pkey_export_to_file pem', [$err_pem_no_start_line]); 104// file to export cannot be written 105@openssl_pkey_export_to_file($private_key_file, $invalid_file_for_write); 106expect_openssl_errors('openssl_pkey_export_to_file write', ['2006D002']); 107// successful export 108@openssl_pkey_export($private_key_file_with_pass, $out, 'wrong pwd'); 109expect_openssl_errors('openssl_pkey_export', ['06065064', '0906A065']); 110// invalid x509 for getting public key 111@openssl_pkey_get_public($private_key_file); 112expect_openssl_errors('openssl_pkey_get_public', [$err_pem_no_start_line]); 113// private encrypt with unknown padding 114@openssl_private_encrypt("data", $crypted, $private_key_file, 1000); 115expect_openssl_errors('openssl_private_encrypt', ['04066076']); 116// private decrypt with failed padding check 117@openssl_private_decrypt("data", $crypted, $private_key_file); 118expect_openssl_errors('openssl_private_decrypt', ['04065072']); 119// public encrypt and decrypt with failed padding check and padding 120@openssl_public_encrypt("data", $crypted, $public_key_file, 1000); 121@openssl_public_decrypt("data", $crypted, $public_key_file); 122expect_openssl_errors('openssl_private_(en|de)crypt padding', [$err_pem_no_start_line, '04068076', '04067072']); 123 124// X509 125echo "X509 errors\n"; 126// file for x509 (file:///) fails when opennig (BIO_new_file) 127@openssl_x509_export_to_file("file://" . $invalid_file_for_read, $output_file); 128expect_openssl_errors('openssl_x509_export_to_file open', ['02001002']); 129// file or str cert is not correct PEM - failing PEM_read_bio_X509 or PEM_ASN1_read_bio 130@openssl_x509_export_to_file($csr_file, $output_file); 131expect_openssl_errors('openssl_x509_export_to_file pem', [$err_pem_no_start_line]); 132// file to export cannot be written 133@openssl_x509_export_to_file($crt_file, $invalid_file_for_write); 134expect_openssl_errors('openssl_x509_export_to_file write', ['2006D002']); 135// checking purpose fails because there is no such purpose 1000 136@openssl_x509_checkpurpose($crt_file, 1000); 137expect_openssl_errors('openssl_x509_checkpurpose purpose', ['0B086079']); 138 139// CSR 140echo "CSR errors\n"; 141// file for csr (file:///) fails when opennig (BIO_new_file) 142@openssl_csr_get_subject("file://" . $invalid_file_for_read); 143expect_openssl_errors('openssl_csr_get_subject open', ['02001002', '2006D080']); 144// file or str csr is not correct PEM - failing PEM_read_bio_X509_REQ 145@openssl_csr_get_subject($crt_file); 146expect_openssl_errors('openssl_csr_get_subjec pem', [$err_pem_no_start_line]); 147 148// other possible causes that are difficult to catch: 149// - ASN1_STRING_to_UTF8 fails in add_assoc_name_entry 150// - invalid php_x509_request field (NULL) would cause error with CONF_get_string 151 152?> 153--CLEAN-- 154<?php 155$output_file = __DIR__ . "/openssl_error_string_basic_output.tmp"; 156if (is_file($output_file)) { 157 unlink($output_file); 158} 159?> 160--EXPECT-- 161string(89) "error:0607A082:digital envelope routines:EVP_CIPHER_CTX_set_key_length:invalid key length" 162bool(false) 163int(15) 164 165PKEY errors 166openssl_pkey_export_to_file opening: ok 167openssl_pkey_export_to_file pem: ok 168openssl_pkey_export_to_file write: ok 169openssl_pkey_export: ok 170openssl_pkey_get_public: ok 171openssl_private_encrypt: ok 172openssl_private_decrypt: ok 173openssl_private_(en|de)crypt padding: ok 174X509 errors 175openssl_x509_export_to_file open: ok 176openssl_x509_export_to_file pem: ok 177openssl_x509_export_to_file write: ok 178openssl_x509_checkpurpose purpose: ok 179CSR errors 180openssl_csr_get_subject open: ok 181openssl_csr_get_subjec pem: ok 182