}
/* }}} */
-static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded TSRMLS_DC) /* {{{ */
+ #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];
if (file == NULL) {
file = RAND_file_name(buffer, sizeof(buffer));
}
+ PHP_OPENSSL_RAND_ADD_TIME();
if (file == NULL || !RAND_write_file(file)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to write random state");
+ php_error_docref(NULL, E_WARNING, "unable to write random state");
return FAILURE;
}
return SUCCESS;
if ((req->priv_key = EVP_PKEY_new()) != NULL) {
switch(req->priv_key_type) {
case OPENSSL_KEYTYPE_RSA:
- PHP_OPENSSL_RAND_ADD_TIME();
- if (EVP_PKEY_assign_RSA(req->priv_key, RSA_generate_key(req->priv_key_bits, 0x10001, NULL, NULL))) {
- return_val = req->priv_key;
+ {
+ 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
+ {
+ BIGNUM *bne = (BIGNUM *)BN_new();
+ if (BN_set_word(bne, RSA_F4) != 1) {
+ BN_free(bne);
+ php_error_docref(NULL, E_WARNING, "failed setting exponent");
+ return NULL;
+ }
+ rsaparam = RSA_new();
++ PHP_OPENSSL_RAND_ADD_TIME();
+ RSA_generate_key_ex(rsaparam, req->priv_key_bits, bne, NULL);
+ BN_free(bne);
+ }
+#endif
+ if (rsaparam && EVP_PKEY_assign_RSA(req->priv_key, rsaparam)) {
+ return_val = req->priv_key;
+ }
}
break;
-#if !defined(NO_DSA) && defined(HAVE_DSA_DEFAULT_METHOD)
+#if !defined(NO_DSA)
case OPENSSL_KEYTYPE_DSA:
+ PHP_OPENSSL_RAND_ADD_TIME();
{
- DSA *dsapar = DSA_generate_parameters(req->priv_key_bits, NULL, 0, NULL, NULL, NULL, NULL);
- if (dsapar) {
- DSA_set_method(dsapar, DSA_get_default_method());
- if (DSA_generate_key(dsapar)) {
- if (EVP_PKEY_assign_DSA(req->priv_key, dsapar)) {
+ DSA *dsaparam = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ dsaparam = DSA_generate_parameters(req->priv_key_bits, NULL, 0, NULL, NULL, NULL, NULL);
+#else
+ DSA_generate_parameters_ex(dsaparam, req->priv_key_bits, NULL, 0, NULL, NULL, NULL);
+#endif
+ if (dsaparam) {
+ DSA_set_method(dsaparam, DSA_get_default_method());
+ if (DSA_generate_key(dsaparam)) {
+ if (EVP_PKEY_assign_DSA(req->priv_key, dsaparam)) {
return_val = req->priv_key;
}
} else {
#endif
#if !defined(NO_DH)
case OPENSSL_KEYTYPE_DH:
+ PHP_OPENSSL_RAND_ADD_TIME();
{
- DH *dhpar = DH_generate_parameters(req->priv_key_bits, 2, NULL, NULL);
int codes = 0;
-
- if (dhpar) {
- DH_set_method(dhpar, DH_get_default_method());
- if (DH_check(dhpar, &codes) && codes == 0 && DH_generate_key(dhpar)) {
- if (EVP_PKEY_assign_DH(req->priv_key, dhpar)) {
+ DH *dhparam = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ dhparam = DH_generate_parameters(req->priv_key_bits, 2, NULL, NULL);
+#else
+ DH_generate_parameters_ex(dhparam, req->priv_key_bits, 2, NULL);
+#endif
+ if (dhparam) {
+ DH_set_method(dhparam, DH_get_default_method());
+ if (DH_check(dhparam, &codes) && codes == 0 && DH_generate_key(dhparam)) {
+ if (EVP_PKEY_assign_DH(req->priv_key, dhparam)) {
return_val = req->priv_key;
}
} else {
EVP_PKEY_free(pkey);
}
RETURN_FALSE;
- } else if (zend_hash_find(Z_ARRVAL_P(args), "dsa", sizeof("dsa"), (void**)&data) == SUCCESS &&
- Z_TYPE_PP(data) == IS_ARRAY) {
- pkey = EVP_PKEY_new();
- if (pkey) {
+ } else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "dsa", sizeof("dsa") - 1)) != NULL &&
+ Z_TYPE_P(data) == IS_ARRAY) {
+ pkey = EVP_PKEY_new();
+ if (pkey) {
DSA *dsa = DSA_new();
if (dsa) {
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, p);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, q);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, g);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, priv_key);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, pub_key);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, p);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, q);
+ 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);
- }
+ if (php_openssl_pkey_init_dsa(dsa)) {
if (EVP_PKEY_assign_DSA(pkey, dsa)) {
- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ RETURN_RES(zend_register_resource(pkey, le_key));
}
}
DSA_free(dsa);
EVP_PKEY_free(pkey);
}
RETURN_FALSE;
- } else if (zend_hash_find(Z_ARRVAL_P(args), "dh", sizeof("dh"), (void**)&data) == SUCCESS &&
- Z_TYPE_PP(data) == IS_ARRAY) {
- pkey = EVP_PKEY_new();
- if (pkey) {
+ } else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "dh", sizeof("dh") - 1)) != NULL &&
+ Z_TYPE_P(data) == IS_ARRAY) {
+ pkey = EVP_PKEY_new();
+ if (pkey) {
DH *dh = DH_new();
if (dh) {
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, p);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, g);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, priv_key);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, pub_key);
+ 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;
+ if (php_openssl_pkey_init_dh(dh)) {
+ if (EVP_PKEY_assign_DH(pkey, dh)) {
- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
++ ZVAL_COPY_VALUE(return_value, zend_list_insert(pkey, le_key));
++ return;
+ }
}
DH_free(dh);
}
RETURN_FALSE;
}
#else
-
+
+ PHP_OPENSSL_CHECK_LONG_TO_INT(buffer_length, length);
- if (RAND_bytes(buffer, buffer_length) <= 0) {
- efree(buffer);
+ 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) {
- ZVAL_BOOL(zstrong_result_returned, 0);
+ ZVAL_FALSE(zstrong_result_returned);
}
RETURN_FALSE;
}