diff options
Diffstat (limited to 'ext/openssl/openssl.c')
-rw-r--r-- | ext/openssl/openssl.c | 113 |
1 files changed, 93 insertions, 20 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 49a5f53caf..b462d0e66c 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -907,10 +907,16 @@ static int add_oid_section(struct php_x509_request * req) /* {{{ */ req->config_filename, req->var, req->req_config) == FAILURE) return FAILURE #define SET_OPTIONAL_STRING_ARG(key, varname, defval) \ - if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_STRING) \ - varname = Z_STRVAL_P(item); \ - else \ - varname = defval + do { \ + if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_STRING) { \ + varname = Z_STRVAL_P(item); \ + } else { \ + varname = defval; \ + if (varname == NULL) { \ + php_openssl_store_errors(); \ + } \ + } \ + } while(0) #define SET_OPTIONAL_LONG_ARG(key, varname, defval) \ if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_LONG) \ @@ -988,9 +994,8 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option str = CONF_get_string(req->req_config, req->section_name, "encrypt_rsa_key"); if (str == NULL) { str = CONF_get_string(req->req_config, req->section_name, "encrypt_key"); - if (str == NULL) { - php_openssl_store_errors(); - } + /* it is sure that there are some errrors as str was NULL for encrypt_rsa_key */ + php_openssl_store_errors(); } if (str != NULL && strcmp(str, "no") == 0) { req->priv_key_encrypt = 0; @@ -1063,6 +1068,22 @@ static void php_openssl_dispose_config(struct php_x509_request * req) /* {{{ */ } /* }}} */ +#ifdef PHP_WIN32 +#define PHP_OPENSSL_RAND_ADD_TIME() ((void) 0) +#else +#define PHP_OPENSSL_RAND_ADD_TIME() php_openssl_rand_add_timeval() + +static inline void php_openssl_rand_add_timeval() /* {{{ */ +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + RAND_add(&tv, sizeof(tv), 0.0); +} +/* }}} */ + +#endif + static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded) /* {{{ */ { char buffer[MAXPATHLEN]; @@ -1106,6 +1127,7 @@ static int php_openssl_write_rand_file(const char * file, int egdsocket, int see if (file == NULL) { file = RAND_file_name(buffer, sizeof(buffer)); } + PHP_OPENSSL_RAND_ADD_TIME(); if (file == NULL || !RAND_write_file(file)) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "unable to write random state"); @@ -1404,6 +1426,9 @@ PHP_MSHUTDOWN_FUNCTION(openssl) EVP_cleanup(); #if OPENSSL_VERSION_NUMBER >= 0x00090805f + /* prevent accessing locking callback from unloaded extension */ + CRYPTO_set_locking_callback(NULL); + /* free allocated error strings */ ERR_free_strings(); #endif @@ -2927,6 +2952,11 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(attribs), strindex, item) { int nid; + if (NULL == strindex) { + php_error_docref(NULL, E_WARNING, "dn: numeric fild names are not supported"); + continue; + } + convert_to_string_ex(item); nid = OBJ_txt2nid(ZSTR_VAL(strindex)); @@ -3619,6 +3649,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req RSA* rsaparam; #if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 deprecates RSA_generate_key */ + PHP_OPENSSL_RAND_ADD_TIME(); rsaparam = (RSA*)RSA_generate_key(req->priv_key_bits, RSA_F4, NULL, NULL); #else { @@ -3629,6 +3660,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req return NULL; } rsaparam = RSA_new(); + PHP_OPENSSL_RAND_ADD_TIME(); if (rsaparam == NULL || !RSA_generate_key_ex(rsaparam, req->priv_key_bits, bne, NULL)) { php_openssl_store_errors(); } @@ -3644,6 +3676,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req break; #if !defined(NO_DSA) case OPENSSL_KEYTYPE_DSA: + PHP_OPENSSL_RAND_ADD_TIME(); { DSA *dsaparam = NULL; #if OPENSSL_VERSION_NUMBER < 0x10002000L @@ -3671,6 +3704,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req #endif #if !defined(NO_DH) case OPENSSL_KEYTYPE_DH: + PHP_OPENSSL_RAND_ADD_TIME(); { int codes = 0; DH *dhparam = NULL; @@ -3791,6 +3825,48 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey) } \ } while (0); +/* {{{ php_openssl_pkey_init_dsa */ +zend_bool php_openssl_pkey_init_dsa(DSA *dsa) +{ + if (!dsa->p || !dsa->q || !dsa->g) { + return 0; + } + if (dsa->priv_key || dsa->pub_key) { + return 1; + } + PHP_OPENSSL_RAND_ADD_TIME(); + if (!DSA_generate_key(dsa)) { + php_openssl_store_errors(); + return 0; + } + /* if BN_mod_exp return -1, then DSA_generate_key succeed for failed key + * so we need to double check that public key is created */ + if (!dsa->pub_key || BN_is_zero(dsa->pub_key)) { + return 0; + } + /* all good */ + return 1; +} +/* }}} */ + +/* {{{ php_openssl_pkey_init_dh */ +zend_bool php_openssl_pkey_init_dh(DH *dh) +{ + if (!dh->p || !dh->g) { + return 0; + } + if (dh->pub_key) { + return 1; + } + PHP_OPENSSL_RAND_ADD_TIME(); + if (!DH_generate_key(dh)) { + php_openssl_store_errors(); + return 0; + } + /* all good */ + return 1; +} +/* }}} */ /* {{{ proto resource openssl_pkey_new([array configargs]) Generates a new private key */ @@ -3849,10 +3925,7 @@ PHP_FUNCTION(openssl_pkey_new) OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, g); OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, priv_key); OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, pub_key); - if (dsa->p && dsa->q && dsa->g) { - if (!dsa->priv_key && !dsa->pub_key && !DSA_generate_key(dsa)) { - php_openssl_store_errors(); - } + if (php_openssl_pkey_init_dsa(dsa)) { if (EVP_PKEY_assign_DSA(pkey, dsa)) { RETURN_RES(zend_register_resource(pkey, le_key)); } else { @@ -3877,14 +3950,14 @@ PHP_FUNCTION(openssl_pkey_new) OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, p); OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, g); OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, priv_key); - OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, pub_key); - if (dh->p && dh->g && - (dh->pub_key || DH_generate_key(dh)) && - EVP_PKEY_assign_DH(pkey, dh)) { - ZVAL_COPY_VALUE(return_value, zend_list_insert(pkey, le_key)); - return; - } else { - php_openssl_store_errors(); + OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, pub_key);php_openssl_store_errors(); + if (php_openssl_pkey_init_dh(dh)) { + if (EVP_PKEY_assign_DH(pkey, dh)) { + ZVAL_COPY_VALUE(return_value, zend_list_insert(pkey, le_key)); + return; + } else { + php_openssl_store_errors(); + } } DH_free(dh); } else { @@ -5990,7 +6063,7 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) #else PHP_OPENSSL_CHECK_LONG_TO_INT(buffer_length, length); - + PHP_OPENSSL_RAND_ADD_TIME(); if (RAND_bytes((unsigned char*)ZSTR_VAL(buffer), (int)buffer_length) <= 0) { zend_string_release(buffer); if (zstrong_result_returned) { |