From 0b82e05fe264306004119e30119e665365331e17 Mon Sep 17 00:00:00 2001 From: Ondřej Surý Date: Fri, 16 Nov 2012 13:25:37 +0100 Subject: Imported Upstream version 5.5.0~alpha1 --- ext/openssl/CREDITS | 2 +- ext/openssl/openssl.c | 321 ++++++++++++++++++++-------------- ext/openssl/php_openssl.h | 2 + ext/openssl/tests/openssl_pbkdf2.phpt | 26 +++ ext/openssl/xp_ssl.c | 4 +- 5 files changed, 222 insertions(+), 133 deletions(-) create mode 100644 ext/openssl/tests/openssl_pbkdf2.phpt (limited to 'ext/openssl') diff --git a/ext/openssl/CREDITS b/ext/openssl/CREDITS index c2f50d630..b685ce13e 100644 --- a/ext/openssl/CREDITS +++ b/ext/openssl/CREDITS @@ -1,2 +1,2 @@ OpenSSL -Stig Venaas, Wez Furlong, Sascha Kettler +Stig Venaas, Wez Furlong, Sascha Kettler, Scott MacVicar diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 2b8cfd571..99735b154 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -16,7 +16,7 @@ | Wez Furlong | | Sascha Kettler | | Pierre-Alain Joye | - | Marc Delling (PKCS12 functions) | + | Marc Delling (PKCS12 functions) | +----------------------------------------------------------------------+ */ @@ -36,10 +36,6 @@ #include "ext/standard/md5.h" #include "ext/standard/base64.h" -#if PHP_WIN32 -# include "win32/winutil.h" -#endif - /* OpenSSL includes */ #include #include @@ -248,6 +244,16 @@ ZEND_BEGIN_ARG_INFO(arginfo_openssl_pkey_get_details, 0) ZEND_ARG_INFO(0, key) ZEND_END_ARG_INFO() +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pbkdf2, 0, 0, 4) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, salt) + ZEND_ARG_INFO(0, key_length) + ZEND_ARG_INFO(0, iterations) + ZEND_ARG_INFO(0, digest_algorithm) +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pkcs7_verify, 0, 0, 2) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, flags) @@ -434,6 +440,10 @@ const zend_function_entry openssl_functions[] = { PHP_FE(openssl_seal, arginfo_openssl_seal) PHP_FE(openssl_open, arginfo_openssl_open) +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + PHP_FE(openssl_pbkdf2, arginfo_openssl_pbkdf2) +#endif + /* for S/MIME handling */ PHP_FE(openssl_pkcs7_verify, arginfo_openssl_pkcs7_verify) PHP_FE(openssl_pkcs7_decrypt, arginfo_openssl_pkcs7_decrypt) @@ -516,7 +526,7 @@ inline static int php_openssl_open_base_dir_chk(char *filename TSRMLS_DC) if (php_check_open_basedir(filename TSRMLS_CC)) { return -1; } - + return 0; } /* }}} */ @@ -575,7 +585,7 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s } else { subitem = val; } - + for (i = 0; i < X509_NAME_entry_count(name); i++) { unsigned char *to_add; int to_add_len; @@ -618,7 +628,7 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s last = j; } i = last; - + if (obj_cnt > 1) { add_assoc_zval_ex(subitem, sname, strlen(sname) + 1, subentries); } else { @@ -718,7 +728,7 @@ static inline int php_openssl_config_check_syntax(const char * section_label, co #endif { X509V3_CTX ctx; - + X509V3_set_ctx_test(&ctx); X509V3_set_conf_lhash(&ctx, config); if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) { @@ -846,7 +856,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option } - + /* digest alg */ if (req->digest_name == NULL) { req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md"); @@ -868,7 +878,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option } PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section); - + return SUCCESS; } /* }}} */ @@ -1048,10 +1058,10 @@ PHP_MINIT_FUNCTION(openssl) /* register a resource id number with OpenSSL so that we can map SSL -> stream structures in * OpenSSL callbacks */ ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL); - + REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER, CONST_CS|CONST_PERSISTENT); - + /* purposes for cert purpose checking */ REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT); @@ -1110,7 +1120,7 @@ PHP_MINIT_FUNCTION(openssl) REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_192_CBC", PHP_OPENSSL_CIPHER_AES_192_CBC, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_256_CBC", PHP_OPENSSL_CIPHER_AES_256_CBC, CONST_CS|CONST_PERSISTENT); #endif - + /* Values for key types */ REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS|CONST_PERSISTENT); #ifndef NO_DSA @@ -1156,7 +1166,7 @@ PHP_MINIT_FUNCTION(openssl) php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC); php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC); - + return SUCCESS; } /* }}} */ @@ -1376,14 +1386,14 @@ PHP_FUNCTION(openssl_x509_check_private_key) long certresource = -1, keyresource = -1; RETVAL_FALSE; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) { return; } cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC); if (cert == NULL) { RETURN_FALSE; - } + } key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC); if (key) { RETVAL_BOOL(X509_check_private_key(cert, key)); @@ -1436,11 +1446,11 @@ PHP_FUNCTION(openssl_x509_parse) snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert)); add_assoc_string(return_value, "hash", buf, 1); } - + add_assoc_name_entry(return_value, "issuer", X509_get_issuer_name(cert), useshortnames TSRMLS_CC); add_assoc_long(return_value, "version", X509_get_version(cert)); - add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1); + add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1); add_assoc_asn1_string(return_value, "validFrom", X509_get_notBefore(cert)); add_assoc_asn1_string(return_value, "validTo", X509_get_notAfter(cert)); @@ -1642,8 +1652,8 @@ clean_exit: if (certresource == 1 && cert) { X509_free(cert); } - if (cainfo) { - X509_STORE_free(cainfo); + if (cainfo) { + X509_STORE_free(cainfo); } if (untrustedchain) { sk_X509_pop_free(untrustedchain, X509_free); @@ -1696,7 +1706,7 @@ static X509_STORE * setup_verify(zval * calist TSRMLS_DC) dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_PP(item), X509_FILETYPE_PEM)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_PP(item)); - } else { + } else { ndirs++; } dir_lookup = NULL; @@ -1790,11 +1800,11 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */ if (certresource != -1) { cert = X509_dup(cert); - + if (cert == NULL) { goto clean_exit; } - + } sk_X509_push(sk, cert); @@ -1803,7 +1813,7 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */ } else { /* a single certificate */ cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC); - + if (cert == NULL) { goto clean_exit; } @@ -1844,7 +1854,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) return; RETVAL_FALSE; - + cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC); if (cert == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1"); @@ -1880,9 +1890,9 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0); - bio_out = BIO_new_file(filename, "w"); + bio_out = BIO_new_file(filename, "w"); if (bio_out) { - + i2d_PKCS12_bio(bio_out, p12); RETVAL_TRUE; @@ -1893,13 +1903,13 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) BIO_free(bio_out); PKCS12_free(p12); php_sk_X509_free(ca); - + cleanup: if (keyresource == -1 && priv_key) { EVP_PKEY_free(priv_key); } - if (certresource == -1 && cert) { + if (certresource == -1 && cert) { X509_free(cert); } } @@ -1925,7 +1935,7 @@ PHP_FUNCTION(openssl_pkcs12_export) return; RETVAL_FALSE; - + cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC); if (cert == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1"); @@ -1948,7 +1958,7 @@ PHP_FUNCTION(openssl_pkcs12_export) if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS) ca = php_array_to_X509_sk(item TSRMLS_CC); /* end parse extra config */ - + p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0); bio_out = BIO_new(BIO_s_mem()); @@ -1965,13 +1975,13 @@ PHP_FUNCTION(openssl_pkcs12_export) BIO_free(bio_out); PKCS12_free(p12); php_sk_X509_free(ca); - + cleanup: if (keyresource == -1 && priv_key) { EVP_PKEY_free(priv_key); } - if (certresource == -1 && cert) { + if (certresource == -1 && cert) { X509_free(cert); } } @@ -1995,12 +2005,12 @@ PHP_FUNCTION(openssl_pkcs12_read) return; RETVAL_FALSE; - + bio_in = BIO_new(BIO_s_mem()); - + if(!BIO_write(bio_in, zp12, zp12_len)) goto cleanup; - + if(d2i_PKCS12_bio(bio_in, &p12)) { if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) { BIO * bio_out; @@ -2030,12 +2040,12 @@ PHP_FUNCTION(openssl_pkcs12_read) MAKE_STD_ZVAL(zextracerts); array_init(zextracerts); - + for (i=0;;i++) { zval * zextracert; X509* aCA = sk_X509_pop(ca); if (!aCA) break; - + bio_out = BIO_new(BIO_s_mem()); if (PEM_write_bio_X509(bio_out, aCA)) { BUF_MEM *bio_buf; @@ -2043,7 +2053,7 @@ PHP_FUNCTION(openssl_pkcs12_read) MAKE_STD_ZVAL(zextracert); ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1); add_index_zval(zextracerts, i, zextracert); - + } BIO_free(bio_out); @@ -2055,13 +2065,13 @@ PHP_FUNCTION(openssl_pkcs12_read) } else { zval_dtor(zextracerts); } - + RETVAL_TRUE; - + PKCS12_free(p12); } } - + cleanup: if (bio_in) { BIO_free(bio_in); @@ -2069,7 +2079,7 @@ PHP_FUNCTION(openssl_pkcs12_read) if (pkey) { EVP_PKEY_free(pkey); } - if (cert) { + if (cert) { X509_free(cert); } } @@ -2088,7 +2098,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z return FAILURE; } dn_sk = CONF_get_section(req->req_config, dn_sect); - if (dn_sk == NULL) { + if (dn_sk == NULL) { return FAILURE; } attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes"); @@ -2108,15 +2118,15 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z X509_NAME * subj; HashPosition hpos; zval ** item; - + subj = X509_REQ_get_subject_name(csr); /* apply values from the dn hash */ zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos); while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) { - char * strindex = NULL; + char * strindex = NULL; uint strindexlen = 0; ulong intindex; - + zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos); convert_to_string_ex(item); @@ -2126,7 +2136,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z nid = OBJ_txt2nid(strindex); if (nid != NID_undef) { - if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8, + if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8, (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, @@ -2147,10 +2157,10 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { int len; char buffer[200 + 1]; /*200 + \0 !*/ - + v = sk_CONF_VALUE_value(dn_sk, i); type = v->name; - + len = strlen(type); if (len < sizeof("_default")) { continue; @@ -2165,7 +2175,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z memcpy(buffer, type, len); buffer[len] = '\0'; type = buffer; - + /* Skip past any leading X. X: X, etc to allow for multiple * instances */ for (str = type; *str; str++) { @@ -2246,7 +2256,7 @@ static X509_REQ * php_openssl_csr_from_zval(zval ** val, int makeresource, long X509_REQ * csr = NULL; char * filename = NULL; BIO * in; - + if (resourceval) { *resourceval = -1; } @@ -2387,13 +2397,13 @@ PHP_FUNCTION(openssl_csr_sign) long csr_resource, certresource = 0, keyresource = -1; int i; struct php_x509_request req; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ!Zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE) return; RETVAL_FALSE; PHP_SSL_REQ_INIT(&req); - + csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC); if (csr == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1"); @@ -2415,7 +2425,7 @@ PHP_FUNCTION(openssl_csr_sign) php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert"); goto cleanup; } - + if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) { goto cleanup; } @@ -2435,9 +2445,9 @@ PHP_FUNCTION(openssl_csr_sign) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request"); goto cleanup; } - + /* Now we can get on with it */ - + new_cert = X509_new(); if (new_cert == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory"); @@ -2448,7 +2458,7 @@ PHP_FUNCTION(openssl_csr_sign) goto cleanup; ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial); - + X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr)); if (cert == NULL) { @@ -2465,7 +2475,7 @@ PHP_FUNCTION(openssl_csr_sign) } if (req.extensions_section) { X509V3_CTX ctx; - + X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0); X509V3_set_conf_lhash(&ctx, req.req_config); if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) { @@ -2478,11 +2488,11 @@ PHP_FUNCTION(openssl_csr_sign) php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it"); goto cleanup; } - + /* Succeeded; lets return the cert */ RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509 TSRMLS_CC)); new_cert = NULL; - + cleanup: if (cert == new_cert) { @@ -2499,7 +2509,7 @@ cleanup: if (csr_resource == -1 && csr) { X509_REQ_free(csr); } - if (certresource == -1 && cert) { + if (certresource == -1 && cert) { X509_free(cert); } if (new_cert) { @@ -2518,12 +2528,12 @@ PHP_FUNCTION(openssl_csr_new) X509_REQ * csr = NULL; int we_made_the_key = 1; long key_resource; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) { return; } RETVAL_FALSE; - + PHP_SSL_REQ_INIT(&req); if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) { @@ -2555,10 +2565,10 @@ PHP_FUNCTION(openssl_csr_new) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section); } else { RETVAL_TRUE; - + if (X509_REQ_sign(csr, req.priv_key, req.digest)) { RETVAL_RESOURCE(zend_list_insert(csr, le_csr TSRMLS_CC)); - csr = NULL; + csr = NULL; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request"); } @@ -2683,14 +2693,14 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char * } if (Z_TYPE_PP(val) == IS_ARRAY) { zval ** zphrase; - + /* get passphrase */ if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)"); return NULL; } - + if (Z_TYPE_PP(zphrase) == IS_STRING) { passphrase = Z_STRVAL_PP(zphrase); } else { @@ -2715,7 +2725,7 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char * if (!what) { TMP_CLEAN; } - if (resourceval) { + if (resourceval) { *resourceval = Z_LVAL_PP(val); } if (type == le_x509) { @@ -2749,8 +2759,8 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char * } } else { /* force it to be a string and check if it refers to a file */ - /* passing non string values leaks, object uses toString, it returns NULL - * See bug38255.phpt + /* passing non string values leaks, object uses toString, it returns NULL + * See bug38255.phpt */ if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) { TMP_CLEAN; @@ -2824,7 +2834,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req char * randfile = NULL; int egdsocket, seeded; EVP_PKEY * return_val = NULL; - + if (req->priv_key_bits < MIN_KEY_LENGTH) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d", MIN_KEY_LENGTH, req->priv_key_bits); @@ -2833,7 +2843,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE"); php_openssl_load_rand_file(randfile, &egdsocket, &seeded TSRMLS_CC); - + if ((req->priv_key = EVP_PKEY_new()) != NULL) { switch(req->priv_key_type) { case OPENSSL_KEYTYPE_RSA: @@ -2883,13 +2893,13 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req } php_openssl_write_rand_file(randfile, egdsocket, seeded); - + if (return_val == NULL) { EVP_PKEY_free(req->priv_key); req->priv_key = NULL; return NULL; } - + return return_val; } /* }}} */ @@ -2918,7 +2928,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC) case EVP_PKEY_DSA4: assert(pkey->pkey.dsa != NULL); - if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){ + if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){ return 0; } break; @@ -3049,7 +3059,7 @@ PHP_FUNCTION(openssl_pkey_new) } RETURN_FALSE; } - } + } PHP_SSL_REQ_INIT(&req); @@ -3078,7 +3088,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file) EVP_PKEY * key; BIO * bio_out = NULL; const EVP_CIPHER * cipher; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) { return; } @@ -3090,11 +3100,11 @@ PHP_FUNCTION(openssl_pkey_export_to_file) php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1"); RETURN_FALSE; } - + if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) { RETURN_FALSE; } - + PHP_SSL_REQ_INIT(&req); if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) { @@ -3137,7 +3147,7 @@ PHP_FUNCTION(openssl_pkey_export) EVP_PKEY * key; BIO * bio_out = NULL; const EVP_CIPHER * cipher; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) { return; } @@ -3149,7 +3159,7 @@ PHP_FUNCTION(openssl_pkey_export) php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1"); RETURN_FALSE; } - + PHP_SSL_REQ_INIT(&req); if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) { @@ -3269,7 +3279,7 @@ PHP_FUNCTION(openssl_pkey_get_details) array_init(return_value); add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey)); add_assoc_stringl(return_value, "key", pbio, pbio_len, 1); - /*TODO: Use the real values once the openssl constants are used + /*TODO: Use the real values once the openssl constants are used * See the enum at the top of this file */ switch (EVP_PKEY_type(pkey->type)) { @@ -3293,7 +3303,7 @@ PHP_FUNCTION(openssl_pkey_get_details) add_assoc_zval(return_value, "rsa", rsa); } - break; + break; case EVP_PKEY_DSA: case EVP_PKEY_DSA2: case EVP_PKEY_DSA3: @@ -3314,7 +3324,7 @@ PHP_FUNCTION(openssl_pkey_get_details) } break; case EVP_PKEY_DH: - + ktype = OPENSSL_KEYTYPE_DH; if (pkey->pkey.dh != NULL) { @@ -3330,7 +3340,7 @@ PHP_FUNCTION(openssl_pkey_get_details) } break; -#ifdef EVP_PKEY_EC +#ifdef EVP_PKEY_EC case EVP_PKEY_EC: ktype = OPENSSL_KEYTYPE_EC; break; @@ -3347,6 +3357,57 @@ PHP_FUNCTION(openssl_pkey_get_details) /* }}} */ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + +/* {{{ proto string openssl_pbkdf2(string password, string salt, long key_length, long iterations [, string digest_method = "sha1"]) + Generates a PKCS5 v2 PBKDF2 string, defaults to sha1 */ +PHP_FUNCTION(openssl_pbkdf2) +{ + long key_length = 0, iterations = 0; + char *password; int password_len; + char *salt; int salt_len; + char *method; int method_len = 0; + unsigned char *out_buffer; + + const EVP_MD *digest; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssll|s", + &password, &password_len, + &salt, &salt_len, + &key_length, &iterations, + &method, &method_len) == FAILURE) { + return; + } + + if (key_length <= 0) { + RETURN_FALSE; + } + + if (method_len) { + digest = EVP_get_digestbyname(method); + } else { + digest = EVP_sha1(); + } + + if (!digest) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm"); + RETURN_FALSE; + } + + out_buffer = emalloc(key_length + 1); + out_buffer[key_length] = '\0'; + + if (PKCS5_PBKDF2_HMAC(password, password_len, (unsigned char *)salt, salt_len, iterations, digest, key_length, out_buffer) == 1) { + RETVAL_STRINGL((char *)out_buffer, key_length, 0); + } else { + efree(out_buffer); + RETURN_FALSE; + } +} +/* }}} */ + +#endif + /* {{{ PKCS7 S/MIME functions */ /* {{{ proto bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content]]]]) @@ -3364,7 +3425,7 @@ PHP_FUNCTION(openssl_pkcs7_verify) char * extracerts = NULL; int extracerts_len = 0; char * signersfilename = NULL; int signersfilename_len = 0; char * datafilename = NULL; int datafilename_len = 0; - + RETVAL_LONG(-1); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pl|papp", &filename, &filename_len, @@ -3372,7 +3433,7 @@ PHP_FUNCTION(openssl_pkcs7_verify) &extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) { return; } - + if (extracerts) { others = load_all_certs_from_file(extracerts); if (others == NULL) { @@ -3424,11 +3485,11 @@ PHP_FUNCTION(openssl_pkcs7_verify) if (signersfilename) { BIO *certout; - + if (php_openssl_open_base_dir_chk(signersfilename TSRMLS_CC)) { goto clean_exit; } - + certout = BIO_new_file(signersfilename, "w"); if (certout) { int i; @@ -3477,14 +3538,14 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) char * strindex; char * infilename = NULL; int infilename_len; char * outfilename = NULL; int outfilename_len; - + RETVAL_FALSE; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZa!|ll", &infilename, &infilename_len, &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE) return; - + if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) { return; } @@ -3495,7 +3556,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) } outfile = BIO_new_file(outfilename, "w"); - if (outfile == NULL) { + if (outfile == NULL) { goto clean_exit; } @@ -3622,12 +3683,12 @@ PHP_FUNCTION(openssl_pkcs7_sign) &extracertsfilename_len) == FAILURE) { return; } - + RETVAL_FALSE; if (extracertsfilename) { others = load_all_certs_from_file(extracertsfilename); - if (others == NULL) { + if (others == NULL) { goto clean_exit; } } @@ -3738,7 +3799,7 @@ PHP_FUNCTION(openssl_pkcs7_decrypt) php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key"); goto clean_exit; } - + if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) { goto clean_exit; } @@ -3757,7 +3818,7 @@ PHP_FUNCTION(openssl_pkcs7_decrypt) if (p7 == NULL) { goto clean_exit; } - if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) { + if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) { RETVAL_TRUE; } clean_exit: @@ -3790,7 +3851,7 @@ PHP_FUNCTION(openssl_private_encrypt) int data_len; long padding = RSA_PKCS1_PADDING; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { return; } RETVAL_FALSE; @@ -3808,10 +3869,10 @@ PHP_FUNCTION(openssl_private_encrypt) switch (pkey->type) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: - successful = (RSA_private_encrypt(data_len, - (unsigned char *)data, - cryptedbuf, - pkey->pkey.rsa, + successful = (RSA_private_encrypt(data_len, + (unsigned char *)data, + cryptedbuf, + pkey->pkey.rsa, padding) == cryptedlen); break; default: @@ -3828,7 +3889,7 @@ PHP_FUNCTION(openssl_private_encrypt) if (cryptedbuf) { efree(cryptedbuf); } - if (keyresource == -1) { + if (keyresource == -1) { EVP_PKEY_free(pkey); } } @@ -3866,10 +3927,10 @@ PHP_FUNCTION(openssl_private_decrypt) switch (pkey->type) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: - cryptedlen = RSA_private_decrypt(data_len, - (unsigned char *)data, - crypttemp, - pkey->pkey.rsa, + cryptedlen = RSA_private_decrypt(data_len, + (unsigned char *)data, + crypttemp, + pkey->pkey.rsa, padding); if (cryptedlen != -1) { cryptedbuf = emalloc(cryptedlen + 1); @@ -3894,7 +3955,7 @@ PHP_FUNCTION(openssl_private_decrypt) if (keyresource == -1) { EVP_PKEY_free(pkey); } - if (cryptedbuf) { + if (cryptedbuf) { efree(cryptedbuf); } } @@ -3918,7 +3979,7 @@ PHP_FUNCTION(openssl_public_encrypt) return; RETVAL_FALSE; - + pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC); if (pkey == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key"); @@ -3931,10 +3992,10 @@ PHP_FUNCTION(openssl_public_encrypt) switch (pkey->type) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: - successful = (RSA_public_encrypt(data_len, - (unsigned char *)data, - cryptedbuf, - pkey->pkey.rsa, + successful = (RSA_public_encrypt(data_len, + (unsigned char *)data, + cryptedbuf, + pkey->pkey.rsa, padding) == cryptedlen); break; default: @@ -3977,7 +4038,7 @@ PHP_FUNCTION(openssl_public_decrypt) return; } RETVAL_FALSE; - + pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC); if (pkey == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key"); @@ -3990,10 +4051,10 @@ PHP_FUNCTION(openssl_public_decrypt) switch (pkey->type) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: - cryptedlen = RSA_public_decrypt(data_len, - (unsigned char *)data, - crypttemp, - pkey->pkey.rsa, + cryptedlen = RSA_public_decrypt(data_len, + (unsigned char *)data, + crypttemp, + pkey->pkey.rsa, padding); if (cryptedlen != -1) { cryptedbuf = emalloc(cryptedlen + 1); @@ -4001,10 +4062,10 @@ PHP_FUNCTION(openssl_public_decrypt) successful = 1; } break; - + default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!"); - + } efree(crypttemp); @@ -4122,7 +4183,7 @@ PHP_FUNCTION(openssl_verify) char * signature; int signature_len; zval *method = NULL; long signature_algo = OPENSSL_ALGO_SHA1; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) { return; } @@ -4181,7 +4242,7 @@ PHP_FUNCTION(openssl_seal) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) { return; } - + pubkeysht = HASH_OF(pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; if (!nkeys) { @@ -4276,7 +4337,7 @@ clean_exit: if (key_resources[i] == -1) { EVP_PKEY_free(pkeys[i]); } - if (eks[i]) { + if (eks[i]) { efree(eks[i]); } } @@ -4322,13 +4383,13 @@ PHP_FUNCTION(openssl_open) } else { cipher = EVP_rc4(); } - + buf = emalloc(data_len + 1); if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) { if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) { efree(buf); - if (keyresource == -1) { + if (keyresource == -1) { EVP_PKEY_free(pkey); } RETURN_FALSE; @@ -4565,7 +4626,7 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff); return NULL; - } + } } tmpssl = SSL_new(ctx); @@ -4622,7 +4683,7 @@ PHP_FUNCTION(openssl_get_md_methods) } array_init(return_value); OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, - aliases ? openssl_add_method_or_alias: openssl_add_method, + aliases ? openssl_add_method_or_alias: openssl_add_method, return_value); } /* }}} */ @@ -4638,7 +4699,7 @@ PHP_FUNCTION(openssl_get_cipher_methods) } array_init(return_value); OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, - aliases ? openssl_add_method_or_alias: openssl_add_method, + aliases ? openssl_add_method_or_alias: openssl_add_method, return_value); } /* }}} */ @@ -4977,7 +5038,7 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) #ifdef PHP_WIN32 strong_result = 1; /* random/urandom equivalent on Windows */ - if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE) { + if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE){ efree(buffer); if (zstrong_result_returned) { ZVAL_BOOL(zstrong_result_returned, 0); diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h index fc118dba1..2de211a64 100644 --- a/ext/openssl/php_openssl.h +++ b/ext/openssl/php_openssl.h @@ -52,6 +52,8 @@ PHP_FUNCTION(openssl_private_decrypt); PHP_FUNCTION(openssl_public_encrypt); PHP_FUNCTION(openssl_public_decrypt); +PHP_FUNCTION(openssl_pbkdf2); + PHP_FUNCTION(openssl_pkcs7_verify); PHP_FUNCTION(openssl_pkcs7_decrypt); PHP_FUNCTION(openssl_pkcs7_sign); diff --git a/ext/openssl/tests/openssl_pbkdf2.phpt b/ext/openssl/tests/openssl_pbkdf2.phpt new file mode 100644 index 000000000..3ec4dce23 --- /dev/null +++ b/ext/openssl/tests/openssl_pbkdf2.phpt @@ -0,0 +1,26 @@ +--TEST-- +openssl_pbkdf2() tests +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +string(40) "0c60c80f961f0e71f3a9b524af6012062fe037a6" +string(40) "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957" +string(40) "4b007901b765489abead49d926f721d065a429c1" +string(50) "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038" +string(32) "56fa6aa75548099dcc37d7f03425e0c3" diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index d03eb3ee8..e9f89f781 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -410,8 +410,8 @@ static inline int php_openssl_setup_crypto(php_stream *stream, if (cparam->inputs.session) { if (cparam->inputs.session->ops != &php_openssl_socket_ops) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied session stream must be an SSL enabled stream"); - } else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied SSL session stream is not initialized"); + } else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied SSL session stream is not initialized"); } else { SSL_copy_session_id(sslsock->ssl_handle, ((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle); } -- cgit v1.2.3