Skip to content

Commit 7566742

Browse files
committed
Suppress OpenSSL error on missing optional config
openssl_pkey_new() fetches various options from the config file -- most of these are optional, and not specifying them is not an error condition from the perspective of the user. Unfortunately, the CONF_get_string() API pushes an error when accessing a key that doesn't exist (_CONF_get_string does not, but that is presumably a private API). This commit adds a helper php_openssl_conf_get_string() that automatically clears the error in this case. I've found that OpenSSL occasionally does the same thing internally: https://github.com/openssl/openssl/blob/22040fb790c854cefb04bed98ed38ea6357daf83/apps/req.c#L515-L517 Closes GH-6699.
1 parent 64b1085 commit 7566742

File tree

2 files changed

+29
-27
lines changed

2 files changed

+29
-27
lines changed

ext/openssl/openssl.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,16 +1064,26 @@ static inline int php_openssl_config_check_syntax(const char * section_label, co
10641064
}
10651065
/* }}} */
10661066

1067+
static char *php_openssl_conf_get_string(
1068+
LHASH_OF(CONF_VALUE) *conf, const char *group, const char *name) {
1069+
char *str = CONF_get_string(conf, group, name);
1070+
if (str == NULL) {
1071+
/* OpenSSL reports an error if a configuration value is not found.
1072+
* However, we don't want to generate errors for optional configuration. */
1073+
ERR_clear_error();
1074+
}
1075+
return str;
1076+
}
1077+
10671078
static int php_openssl_add_oid_section(struct php_x509_request * req) /* {{{ */
10681079
{
10691080
char * str;
10701081
STACK_OF(CONF_VALUE) * sktmp;
10711082
CONF_VALUE * cnf;
10721083
int i;
10731084

1074-
str = CONF_get_string(req->req_config, NULL, "oid_section");
1085+
str = php_openssl_conf_get_string(req->req_config, NULL, "oid_section");
10751086
if (str == NULL) {
1076-
php_openssl_store_errors();
10771087
return SUCCESS;
10781088
}
10791089
sktmp = CONF_get_section(req->req_config, str);
@@ -1158,10 +1168,8 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
11581168
}
11591169

11601170
/* read in the oids */
1161-
str = CONF_get_string(req->req_config, NULL, "oid_file");
1162-
if (str == NULL) {
1163-
php_openssl_store_errors();
1164-
} else if (!php_openssl_open_base_dir_chk(str)) {
1171+
str = php_openssl_conf_get_string(req->req_config, NULL, "oid_file");
1172+
if (str != NULL && !php_openssl_open_base_dir_chk(str)) {
11651173
BIO *oid_bio = BIO_new_file(str, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
11661174
if (oid_bio) {
11671175
OBJ_create_objects(oid_bio);
@@ -1173,11 +1181,11 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
11731181
return FAILURE;
11741182
}
11751183
SET_OPTIONAL_STRING_ARG("digest_alg", req->digest_name,
1176-
CONF_get_string(req->req_config, req->section_name, "default_md"));
1184+
php_openssl_conf_get_string(req->req_config, req->section_name, "default_md"));
11771185
SET_OPTIONAL_STRING_ARG("x509_extensions", req->extensions_section,
1178-
CONF_get_string(req->req_config, req->section_name, "x509_extensions"));
1186+
php_openssl_conf_get_string(req->req_config, req->section_name, "x509_extensions"));
11791187
SET_OPTIONAL_STRING_ARG("req_extensions", req->request_extensions_section,
1180-
CONF_get_string(req->req_config, req->section_name, "req_extensions"));
1188+
php_openssl_conf_get_string(req->req_config, req->section_name, "req_extensions"));
11811189
SET_OPTIONAL_LONG_ARG("private_key_bits", req->priv_key_bits,
11821190
CONF_get_number(req->req_config, req->section_name, "default_bits"));
11831191

@@ -1186,11 +1194,9 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
11861194
if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), "encrypt_key", sizeof("encrypt_key")-1)) != NULL) {
11871195
req->priv_key_encrypt = Z_TYPE_P(item) == IS_TRUE ? 1 : 0;
11881196
} else {
1189-
str = CONF_get_string(req->req_config, req->section_name, "encrypt_rsa_key");
1197+
str = php_openssl_conf_get_string(req->req_config, req->section_name, "encrypt_rsa_key");
11901198
if (str == NULL) {
1191-
str = CONF_get_string(req->req_config, req->section_name, "encrypt_key");
1192-
/* it is sure that there are some errrors as str was NULL for encrypt_rsa_key */
1193-
php_openssl_store_errors();
1199+
str = php_openssl_conf_get_string(req->req_config, req->section_name, "encrypt_key");
11941200
}
11951201
if (str != NULL && strcmp(str, "no") == 0) {
11961202
req->priv_key_encrypt = 0;
@@ -1218,12 +1224,10 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
12181224

12191225
/* digest alg */
12201226
if (req->digest_name == NULL) {
1221-
req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
1227+
req->digest_name = php_openssl_conf_get_string(req->req_config, req->section_name, "default_md");
12221228
}
12231229
if (req->digest_name != NULL) {
12241230
req->digest = req->md_alg = EVP_get_digestbyname(req->digest_name);
1225-
} else {
1226-
php_openssl_store_errors();
12271231
}
12281232
if (req->md_alg == NULL) {
12291233
req->md_alg = req->digest = EVP_sha1();
@@ -1245,10 +1249,8 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
12451249
#endif
12461250

12471251
/* set the string mask */
1248-
str = CONF_get_string(req->req_config, req->section_name, "string_mask");
1249-
if (str == NULL) {
1250-
php_openssl_store_errors();
1251-
} else if (!ASN1_STRING_set_default_mask_asc(str)) {
1252+
str = php_openssl_conf_get_string(req->req_config, req->section_name, "string_mask");
1253+
if (str != NULL && !ASN1_STRING_set_default_mask_asc(str)) {
12521254
php_error_docref(NULL, E_WARNING, "Invalid global string mask setting %s", str);
12531255
return FAILURE;
12541256
}
@@ -3138,9 +3140,8 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
31383140
php_openssl_store_errors();
31393141
return FAILURE;
31403142
}
3141-
attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
3143+
attr_sect = php_openssl_conf_get_string(req->req_config, req->section_name, "attributes");
31423144
if (attr_sect == NULL) {
3143-
php_openssl_store_errors();
31443145
attr_sk = NULL;
31453146
} else {
31463147
attr_sk = CONF_get_section(req->req_config, attr_sect);
@@ -3994,10 +3995,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
39943995
return NULL;
39953996
}
39963997

3997-
randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
3998-
if (randfile == NULL) {
3999-
php_openssl_store_errors();
4000-
}
3998+
randfile = php_openssl_conf_get_string(req->req_config, req->section_name, "RANDFILE");
40013999
php_openssl_load_rand_file(randfile, &egdsocket, &seeded);
40024000

40034001
if ((req->priv_key = EVP_PKEY_new()) != NULL) {

ext/openssl/tests/bug80747.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ $conf = array(
1313
'private_key_bits' => 511,
1414
);
1515
var_dump(openssl_pkey_new($conf));
16+
while ($e = openssl_error_string()) {
17+
echo $e, "\n";
18+
}
1619

1720
?>
18-
--EXPECT--
21+
--EXPECTF--
1922
bool(false)
23+
error:%s:key size too small

0 commit comments

Comments
 (0)