Diff for /embedaddon/php/ext/openssl/openssl.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/21 23:47:59 version 1.1.1.4, 2013/10/14 08:02:27
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2013 The PHP Group                                |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | This source file is subject to version 3.01 of the PHP license,      |     | This source file is subject to version 3.01 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |     | that is bundled with this package in the file LICENSE, and is        |
Line 16 Line 16
    |          Wez Furlong <wez@thebrainroom.com>                          |     |          Wez Furlong <wez@thebrainroom.com>                          |
    |          Sascha Kettler <kettler@gmx.net>                            |     |          Sascha Kettler <kettler@gmx.net>                            |
    |          Pierre-Alain Joye <pierre@php.net>                          |     |          Pierre-Alain Joye <pierre@php.net>                          |
   |          Marc Delling <delling@silpion.de> (PKCS12 functions)        |                |          Marc Delling <delling@silpion.de> (PKCS12 functions)        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
  */   */
   
Line 36 Line 36
 #include "ext/standard/md5.h"  #include "ext/standard/md5.h"
 #include "ext/standard/base64.h"  #include "ext/standard/base64.h"
   
   #if PHP_WIN32
   # include "win32/winutil.h"
   #endif
   
 /* OpenSSL includes */  /* OpenSSL includes */
 #include <openssl/evp.h>  #include <openssl/evp.h>
 #include <openssl/x509.h>  #include <openssl/x509.h>
Line 65 Line 69
 #define OPENSSL_ALGO_MD2        4  #define OPENSSL_ALGO_MD2        4
 #endif  #endif
 #define OPENSSL_ALGO_DSS1       5  #define OPENSSL_ALGO_DSS1       5
#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
 #define OPENSSL_ALGO_SHA224 6
 #define OPENSSL_ALGO_SHA256 7
 #define OPENSSL_ALGO_SHA384 8
 #define OPENSSL_ALGO_SHA512 9
 #define OPENSSL_ALGO_RMD160 10
 #endif
 #define DEBUG_SMIME     0  #define DEBUG_SMIME     0
   
 /* FIXME: Use the openssl constants instead of  /* FIXME: Use the openssl constants instead of
Line 89  enum php_openssl_cipher_type { Line 99  enum php_openssl_cipher_type {
         PHP_OPENSSL_CIPHER_RC2_64,          PHP_OPENSSL_CIPHER_RC2_64,
         PHP_OPENSSL_CIPHER_DES,          PHP_OPENSSL_CIPHER_DES,
         PHP_OPENSSL_CIPHER_3DES,          PHP_OPENSSL_CIPHER_3DES,
           PHP_OPENSSL_CIPHER_AES_128_CBC,
           PHP_OPENSSL_CIPHER_AES_192_CBC,
           PHP_OPENSSL_CIPHER_AES_256_CBC,
   
         PHP_OPENSSL_CIPHER_DEFAULT = PHP_OPENSSL_CIPHER_RC2_40          PHP_OPENSSL_CIPHER_DEFAULT = PHP_OPENSSL_CIPHER_RC2_40
 };  };
Line 347  ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_encrypt, 0, 0,  Line 360  ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_encrypt, 0, 0, 
     ZEND_ARG_INFO(0, data)      ZEND_ARG_INFO(0, data)
     ZEND_ARG_INFO(0, method)      ZEND_ARG_INFO(0, method)
     ZEND_ARG_INFO(0, password)      ZEND_ARG_INFO(0, password)
    ZEND_ARG_INFO(0, raw_output)    ZEND_ARG_INFO(0, options)
     ZEND_ARG_INFO(0, iv)      ZEND_ARG_INFO(0, iv)
 ZEND_END_ARG_INFO()  ZEND_END_ARG_INFO()
   
Line 355  ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_decrypt, 0, 0,  Line 368  ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_decrypt, 0, 0, 
     ZEND_ARG_INFO(0, data)      ZEND_ARG_INFO(0, data)
     ZEND_ARG_INFO(0, method)      ZEND_ARG_INFO(0, method)
     ZEND_ARG_INFO(0, password)      ZEND_ARG_INFO(0, password)
    ZEND_ARG_INFO(0, raw_input)    ZEND_ARG_INFO(0, options)
     ZEND_ARG_INFO(0, iv)      ZEND_ARG_INFO(0, iv)
 ZEND_END_ARG_INFO()  ZEND_END_ARG_INFO()
   
Line 497  static void php_csr_free(zend_rsrc_list_entry *rsrc TS Line 510  static void php_csr_free(zend_rsrc_list_entry *rsrc TS
 }  }
 /* }}} */  /* }}} */
   
/* {{{ openssl safe_mode & open_basedir checks *//* {{{ openssl open_basedir check */
inline static int php_openssl_safe_mode_chk(char *filename TSRMLS_DC)inline static int php_openssl_open_base_dir_chk(char *filename TSRMLS_DC)
 {  {
         if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {  
                 return -1;  
         }  
         if (php_check_open_basedir(filename TSRMLS_CC)) {          if (php_check_open_basedir(filename TSRMLS_CC)) {
                 return -1;                  return -1;
         }          }
        
         return 0;          return 0;
 }  }
 /* }}} */  /* }}} */
Line 536  struct php_x509_request { /* {{{ */ Line 546  struct php_x509_request { /* {{{ */
         int priv_key_encrypt;          int priv_key_encrypt;
   
         EVP_PKEY * priv_key;          EVP_PKEY * priv_key;
   
       const EVP_CIPHER * priv_key_encrypt_cipher;
 };  };
 /* }}} */  /* }}} */
   
Line 549  static EVP_PKEY * php_openssl_generate_private_key(str Line 561  static EVP_PKEY * php_openssl_generate_private_key(str
   
 static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname TSRMLS_DC) /* {{{ */  static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname TSRMLS_DC) /* {{{ */
 {  {
           zval **data;
         zval *subitem, *subentries;          zval *subitem, *subentries;
         int i, j = -1, last = -1, obj_cnt = 0;          int i, j = -1, last = -1, obj_cnt = 0;
         char *sname;          char *sname;
Line 563  static void add_assoc_name_entry(zval * val, char * ke Line 576  static void add_assoc_name_entry(zval * val, char * ke
         } else {          } else {
                 subitem = val;                  subitem = val;
         }          }
        
         for (i = 0; i < X509_NAME_entry_count(name); i++) {          for (i = 0; i < X509_NAME_entry_count(name); i++) {
                 unsigned char *to_add;                  unsigned char *to_add;
                int to_add_len;                int to_add_len = 0;
   
   
                 ne  = X509_NAME_get_entry(name, i);                  ne  = X509_NAME_get_entry(name, i);
Line 580  static void add_assoc_name_entry(zval * val, char * ke Line 593  static void add_assoc_name_entry(zval * val, char * ke
                         sname = (char *) OBJ_nid2ln(nid);                          sname = (char *) OBJ_nid2ln(nid);
                 }                  }
   
                MAKE_STD_ZVAL(subentries);                str = X509_NAME_ENTRY_get_data(ne);
                array_init(subentries);                if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) {
                         to_add_len = ASN1_STRING_to_UTF8(&to_add, str);
                 } else {
                         to_add = ASN1_STRING_data(str);
                         to_add_len = ASN1_STRING_length(str);
                 }
   
                last = -1;                if (to_add_len != -1) {
                for (;;) {                        if (zend_hash_find(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, (void**)&data) == SUCCESS) {
                        j = X509_NAME_get_index_by_OBJ(name, obj, last);                                if (Z_TYPE_PP(data) == IS_ARRAY) {
                        if (j < 0) {                                        subentries = *data;
                                if (last != -1) break; 
                        } else { 
                                obj_cnt++; 
                                ne  = X509_NAME_get_entry(name, j); 
                                str = X509_NAME_ENTRY_get_data(ne); 
                                if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) { 
                                        to_add_len = ASN1_STRING_to_UTF8(&to_add, str); 
                                        if (to_add_len != -1) { 
                                                add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); 
                                        } 
                                } else { 
                                        to_add = ASN1_STRING_data(str); 
                                        to_add_len = ASN1_STRING_length(str); 
                                         add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1);                                          add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1);
                                   } else if (Z_TYPE_PP(data) == IS_STRING) {
                                           MAKE_STD_ZVAL(subentries);
                                           array_init(subentries);
                                           add_next_index_stringl(subentries, Z_STRVAL_PP(data), Z_STRLEN_PP(data), 1);
                                           add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1);
                                           zend_hash_update(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, &subentries, sizeof(zval*), NULL);
                                 }                                  }
                        }                        } else {
                        last = j; 
                } 
                i = last; 
                 
                if (obj_cnt > 1) { 
                        add_assoc_zval_ex(subitem, sname, strlen(sname) + 1, subentries); 
                } else { 
                        zval_dtor(subentries); 
                        FREE_ZVAL(subentries); 
                        if (obj_cnt && str && to_add_len > -1) { 
                                 add_assoc_stringl(subitem, sname, (char *)to_add, to_add_len, 1);                                  add_assoc_stringl(subitem, sname, (char *)to_add, to_add_len, 1);
                         }                          }
                 }                  }
Line 706  static inline int php_openssl_config_check_syntax(cons Line 707  static inline int php_openssl_config_check_syntax(cons
 #endif  #endif
 {  {
         X509V3_CTX ctx;          X509V3_CTX ctx;
        
         X509V3_set_ctx_test(&ctx);          X509V3_set_ctx_test(&ctx);
         X509V3_set_conf_lhash(&ctx, config);          X509V3_set_conf_lhash(&ctx, config);
         if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) {          if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) {
Line 766  static int add_oid_section(struct php_x509_request * r Line 767  static int add_oid_section(struct php_x509_request * r
         else \          else \
                 varname = defval                  varname = defval
   
   static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo);
   
   
 static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args TSRMLS_DC) /* {{{ */  static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args TSRMLS_DC) /* {{{ */
 {  {
         char * str;          char * str;
Line 782  static int php_openssl_parse_config(struct php_x509_re Line 786  static int php_openssl_parse_config(struct php_x509_re
   
         /* read in the oids */          /* read in the oids */
         str = CONF_get_string(req->req_config, NULL, "oid_file");          str = CONF_get_string(req->req_config, NULL, "oid_file");
        if (str && !php_openssl_safe_mode_chk(str TSRMLS_CC)) {        if (str && !php_openssl_open_base_dir_chk(str TSRMLS_CC)) {
                 BIO *oid_bio = BIO_new_file(str, "r");                  BIO *oid_bio = BIO_new_file(str, "r");
                 if (oid_bio) {                  if (oid_bio) {
                         OBJ_create_objects(oid_bio);                          OBJ_create_objects(oid_bio);
Line 816  static int php_openssl_parse_config(struct php_x509_re Line 820  static int php_openssl_parse_config(struct php_x509_re
                         req->priv_key_encrypt = 1;                          req->priv_key_encrypt = 1;
                 }                  }
         }          }
        
         if (req->priv_key_encrypt && optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), "encrypt_key_cipher", sizeof("encrypt_key_cipher"), (void**)&item) == SUCCESS) {
                 long cipher_algo = Z_LVAL_PP(item);
                 const EVP_CIPHER* cipher = php_openssl_get_evp_cipher_from_algo(cipher_algo);
                 if (cipher == NULL) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm for private key.");
                         return FAILURE;
                 } else  {
                         req->priv_key_encrypt_cipher = cipher;
                 }
         } else {
                 req->priv_key_encrypt_cipher = NULL;
         }
 
 
 
         /* digest alg */          /* digest alg */
         if (req->digest_name == NULL) {          if (req->digest_name == NULL) {
                 req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");                  req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
Line 838  static int php_openssl_parse_config(struct php_x509_re Line 857  static int php_openssl_parse_config(struct php_x509_re
         }          }
   
         PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);          PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);
        
         return SUCCESS;          return SUCCESS;
 }  }
 /* }}} */  /* }}} */
Line 860  static void php_openssl_dispose_config(struct php_x509 Line 879  static void php_openssl_dispose_config(struct php_x509
 }  }
 /* }}} */  /* }}} */
   
static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded) /* {{{ */static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded TSRMLS_DC) /* {{{ */
 {  {
         char buffer[MAXPATHLEN];          char buffer[MAXPATHLEN];
   
         TSRMLS_FETCH();  
   
         *egdsocket = 0;          *egdsocket = 0;
         *seeded = 0;          *seeded = 0;
   
Line 932  static EVP_MD * php_openssl_get_evp_md_from_algo(long  Line 949  static EVP_MD * php_openssl_get_evp_md_from_algo(long 
                 case OPENSSL_ALGO_DSS1:                  case OPENSSL_ALGO_DSS1:
                         mdtype = (EVP_MD *) EVP_dss1();                          mdtype = (EVP_MD *) EVP_dss1();
                         break;                          break;
   #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
                   case OPENSSL_ALGO_SHA224:
                           mdtype = (EVP_MD *) EVP_sha224();
                           break;
                   case OPENSSL_ALGO_SHA256:
                           mdtype = (EVP_MD *) EVP_sha256();
                           break;
                   case OPENSSL_ALGO_SHA384:
                           mdtype = (EVP_MD *) EVP_sha384();
                           break;
                   case OPENSSL_ALGO_SHA512:
                           mdtype = (EVP_MD *) EVP_sha512();
                           break;
                   case OPENSSL_ALGO_RMD160:
                           mdtype = (EVP_MD *) EVP_ripemd160();
                           break;
   #endif
                 default:                  default:
                         return NULL;                          return NULL;
                         break;                          break;
Line 962  static const EVP_CIPHER * php_openssl_get_evp_cipher_f Line 996  static const EVP_CIPHER * php_openssl_get_evp_cipher_f
                         return EVP_des_ede3_cbc();                          return EVP_des_ede3_cbc();
                         break;                          break;
 #endif  #endif
   
   #ifndef OPENSSL_NO_AES
                   case PHP_OPENSSL_CIPHER_AES_128_CBC:
                           return EVP_aes_128_cbc();
                           break;
                   case PHP_OPENSSL_CIPHER_AES_192_CBC:
                           return EVP_aes_192_cbc();
                           break;
                   case PHP_OPENSSL_CIPHER_AES_256_CBC:
                           return EVP_aes_256_cbc();
                           break;
   #endif
   
   
                 default:                  default:
                         return NULL;                          return NULL;
                         break;                          break;
Line 984  PHP_MINIT_FUNCTION(openssl) Line 1032  PHP_MINIT_FUNCTION(openssl)
         OpenSSL_add_all_digests();          OpenSSL_add_all_digests();
         OpenSSL_add_all_algorithms();          OpenSSL_add_all_algorithms();
   
        ERR_load_ERR_strings();        SSL_load_error_strings();
        ERR_load_crypto_strings(); 
        ERR_load_EVP_strings(); 
   
         /* register a resource id number with OpenSSL so that we can map SSL -> stream structures in          /* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
          * OpenSSL callbacks */           * OpenSSL callbacks */
         ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL);          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_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);          REGISTER_LONG_CONSTANT("OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER, CONST_CS|CONST_PERSISTENT);
        
         /* purposes for cert purpose checking */          /* 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_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT);
Line 1014  PHP_MINIT_FUNCTION(openssl) Line 1060  PHP_MINIT_FUNCTION(openssl)
         REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD2", OPENSSL_ALGO_MD2, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD2", OPENSSL_ALGO_MD2, CONST_CS|CONST_PERSISTENT);
 #endif  #endif
         REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);
   #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
           REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA224", OPENSSL_ALGO_SHA224, CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA256", OPENSSL_ALGO_SHA256, CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA384", OPENSSL_ALGO_SHA384, CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA512", OPENSSL_ALGO_SHA512, CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("OPENSSL_ALGO_RMD160", OPENSSL_ALGO_RMD160, CONST_CS|CONST_PERSISTENT);
   #endif
   
         /* flags for S/MIME */          /* flags for S/MIME */
         REGISTER_LONG_CONSTANT("PKCS7_DETACHED", PKCS7_DETACHED, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("PKCS7_DETACHED", PKCS7_DETACHED, CONST_CS|CONST_PERSISTENT);
Line 1041  PHP_MINIT_FUNCTION(openssl) Line 1094  PHP_MINIT_FUNCTION(openssl)
         REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_DES", PHP_OPENSSL_CIPHER_DES, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_DES", PHP_OPENSSL_CIPHER_DES, CONST_CS|CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_3DES", PHP_OPENSSL_CIPHER_3DES, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_3DES", PHP_OPENSSL_CIPHER_3DES, CONST_CS|CONST_PERSISTENT);
 #endif  #endif
   #ifndef OPENSSL_NO_AES
           REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_128_CBC", PHP_OPENSSL_CIPHER_AES_128_CBC, CONST_CS|CONST_PERSISTENT);
           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 */          /* Values for key types */
         REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS|CONST_PERSISTENT);
Line 1052  PHP_MINIT_FUNCTION(openssl) Line 1110  PHP_MINIT_FUNCTION(openssl)
         REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_EC", OPENSSL_KEYTYPE_EC, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_EC", OPENSSL_KEYTYPE_EC, CONST_CS|CONST_PERSISTENT);
 #endif  #endif
   
           REGISTER_LONG_CONSTANT("OPENSSL_RAW_DATA", OPENSSL_RAW_DATA, CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("OPENSSL_ZERO_PADDING", OPENSSL_ZERO_PADDING, CONST_CS|CONST_PERSISTENT);
   
 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)  #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
         /* SNI support included in OpenSSL >= 0.9.8j */          /* SNI support included in OpenSSL >= 0.9.8j */
         REGISTER_LONG_CONSTANT("OPENSSL_TLSEXT_SERVER_NAME", 1, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("OPENSSL_TLSEXT_SERVER_NAME", 1, CONST_CS|CONST_PERSISTENT);
Line 1084  PHP_MINIT_FUNCTION(openssl) Line 1145  PHP_MINIT_FUNCTION(openssl)
   
         php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);          php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
         php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);          php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
        
         return SUCCESS;          return SUCCESS;
 }  }
 /* }}} */  /* }}} */
Line 1174  static X509 * php_openssl_x509_from_zval(zval ** val,  Line 1235  static X509 * php_openssl_x509_from_zval(zval ** val, 
                 /* read cert from the named file */                  /* read cert from the named file */
                 BIO *in;                  BIO *in;
   
                if (php_openssl_safe_mode_chk(Z_STRVAL_PP(val) + (sizeof("file://") - 1) TSRMLS_CC)) {                if (php_openssl_open_base_dir_chk(Z_STRVAL_PP(val) + (sizeof("file://") - 1) TSRMLS_CC)) {
                         return NULL;                          return NULL;
                 }                  }
   
Line 1200  static X509 * php_openssl_x509_from_zval(zval ** val,  Line 1261  static X509 * php_openssl_x509_from_zval(zval ** val, 
         }          }
   
         if (cert && makeresource && resourceval) {          if (cert && makeresource && resourceval) {
                *resourceval = zend_list_insert(cert, le_x509);                *resourceval = zend_list_insert(cert, le_x509 TSRMLS_CC);
         }          }
         return cert;          return cert;
 }  }
Line 1219  PHP_FUNCTION(openssl_x509_export_to_file) Line 1280  PHP_FUNCTION(openssl_x509_export_to_file)
         char * filename;          char * filename;
         int filename_len;          int filename_len;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|b", &zcert, &filename, &filename_len, &notext) == FAILURE) {        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|b", &zcert, &filename, &filename_len, &notext) == FAILURE) {
                 return;                  return;
         }          }
         RETVAL_FALSE;          RETVAL_FALSE;
Line 1230  PHP_FUNCTION(openssl_x509_export_to_file) Line 1291  PHP_FUNCTION(openssl_x509_export_to_file)
                 return;                  return;
         }          }
   
        if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
                 return;                  return;
         }          }
   
Line 1304  PHP_FUNCTION(openssl_x509_check_private_key) Line 1365  PHP_FUNCTION(openssl_x509_check_private_key)
         long certresource = -1, keyresource = -1;          long certresource = -1, keyresource = -1;
   
         RETVAL_FALSE;          RETVAL_FALSE;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) {
                 return;                  return;
         }          }
         cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);          cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
         if (cert == NULL) {          if (cert == NULL) {
                 RETURN_FALSE;                  RETURN_FALSE;
        }               }
         key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC);          key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC);
         if (key) {          if (key) {
                 RETVAL_BOOL(X509_check_private_key(cert, key));                  RETVAL_BOOL(X509_check_private_key(cert, key));
Line 1326  PHP_FUNCTION(openssl_x509_check_private_key) Line 1387  PHP_FUNCTION(openssl_x509_check_private_key)
 }  }
 /* }}} */  /* }}} */
   
   /* Special handling of subjectAltName, see CVE-2013-4073
    * Christian Heimes
    */
   
   static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
   {
           GENERAL_NAMES *names;
           const X509V3_EXT_METHOD *method = NULL;
           long i, length, num;
           const unsigned char *p;
   
           method = X509V3_EXT_get(extension);
           if (method == NULL) {
                   return -1;
           }
   
           p = extension->value->data;
           length = extension->value->length;
           if (method->it) {
                   names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
                                                          ASN1_ITEM_ptr(method->it)));
           } else {
                   names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length));
           }
           if (names == NULL) {
                   return -1;
           }
   
           num = sk_GENERAL_NAME_num(names);
           for (i = 0; i < num; i++) {
                           GENERAL_NAME *name;
                           ASN1_STRING *as;
                           name = sk_GENERAL_NAME_value(names, i);
                           switch (name->type) {
                                   case GEN_EMAIL:
                                           BIO_puts(bio, "email:");
                                           as = name->d.rfc822Name;
                                           BIO_write(bio, ASN1_STRING_data(as),
                                                     ASN1_STRING_length(as));
                                           break;
                                   case GEN_DNS:
                                           BIO_puts(bio, "DNS:");
                                           as = name->d.dNSName;
                                           BIO_write(bio, ASN1_STRING_data(as),
                                                     ASN1_STRING_length(as));
                                           break;
                                   case GEN_URI:
                                           BIO_puts(bio, "URI:");
                                           as = name->d.uniformResourceIdentifier;
                                           BIO_write(bio, ASN1_STRING_data(as),
                                                     ASN1_STRING_length(as));
                                           break;
                                   default:
                                           /* use builtin print for GEN_OTHERNAME, GEN_X400,
                                            * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
                                            */
                                           GENERAL_NAME_print(bio, name);
                           }
                           /* trailing ', ' except for last element */
                           if (i < (num - 1)) {
                                   BIO_puts(bio, ", ");
                           }
           }
           sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
   
           return 0;
   }
   
 /* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true])  /* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true])
    Returns an array of the fields/values of the CERT */     Returns an array of the fields/values of the CERT */
 PHP_FUNCTION(openssl_x509_parse)  PHP_FUNCTION(openssl_x509_parse)
Line 1364  PHP_FUNCTION(openssl_x509_parse) Line 1493  PHP_FUNCTION(openssl_x509_parse)
                 snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));                  snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));
                 add_assoc_string(return_value, "hash", buf, 1);                  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_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_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, "validFrom",        X509_get_notBefore(cert));
         add_assoc_asn1_string(return_value, "validTo",          X509_get_notAfter(cert));          add_assoc_asn1_string(return_value, "validTo",          X509_get_notAfter(cert));
Line 1422  PHP_FUNCTION(openssl_x509_parse) Line 1551  PHP_FUNCTION(openssl_x509_parse)
   
   
         for (i = 0; i < X509_get_ext_count(cert); i++) {          for (i = 0; i < X509_get_ext_count(cert); i++) {
                   int nid;
                 extension = X509_get_ext(cert, i);                  extension = X509_get_ext(cert, i);
                if (OBJ_obj2nid(X509_EXTENSION_get_object(extension)) != NID_undef) {                nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
                 if (nid != NID_undef) {
                         extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension)));                          extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension)));
                 } else {                  } else {
                         OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1);                          OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1);
                         extname = buf;                          extname = buf;
                 }                  }
                 bio_out = BIO_new(BIO_s_mem());                  bio_out = BIO_new(BIO_s_mem());
                if (X509V3_EXT_print(bio_out, extension, 0, 0)) {                if (nid == NID_subject_alt_name) {
                         if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
                                 BIO_get_mem_ptr(bio_out, &bio_buf);
                                 add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
                         } else {
                                 zval_dtor(return_value);
                                 if (certresource == -1 && cert) {
                                         X509_free(cert);
                                 }
                                 BIO_free(bio_out);
                                 RETURN_FALSE;
                         }
                 }
                 else if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
                         BIO_get_mem_ptr(bio_out, &bio_buf);                          BIO_get_mem_ptr(bio_out, &bio_buf);
                         add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);                          add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
                 } else {                  } else {
Line 1460  static STACK_OF(X509) * load_all_certs_from_file(char  Line 1604  static STACK_OF(X509) * load_all_certs_from_file(char 
                 goto end;                  goto end;
         }          }
   
        if (php_openssl_safe_mode_chk(certfile TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(certfile TSRMLS_CC)) {
                 sk_X509_free(stack);                  sk_X509_free(stack);
                 goto end;                  goto end;
         }          }
Line 1570  clean_exit: Line 1714  clean_exit:
         if (certresource == 1 && cert) {          if (certresource == 1 && cert) {
                 X509_free(cert);                  X509_free(cert);
         }          }
        if (cainfo) {         if (cainfo) {
                X509_STORE_free(cainfo);                 X509_STORE_free(cainfo);
         }          }
         if (untrustedchain) {          if (untrustedchain) {
                 sk_X509_pop_free(untrustedchain, X509_free);                  sk_X509_pop_free(untrustedchain, X509_free);
Line 1624  static X509_STORE * setup_verify(zval * calist TSRMLS_ Line 1768  static X509_STORE * setup_verify(zval * calist TSRMLS_
                                 dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());                                  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)) {                                  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));                                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_PP(item));
                                } else {                                 } else {
                                         ndirs++;                                          ndirs++;
                                 }                                  }
                                 dir_lookup = NULL;                                  dir_lookup = NULL;
Line 1718  static STACK_OF(X509) * php_array_to_X509_sk(zval ** z Line 1862  static STACK_OF(X509) * php_array_to_X509_sk(zval ** z
   
                         if (certresource != -1) {                          if (certresource != -1) {
                                 cert = X509_dup(cert);                                  cert = X509_dup(cert);
                                
                                 if (cert == NULL) {                                  if (cert == NULL) {
                                         goto clean_exit;                                          goto clean_exit;
                                 }                                  }
                                
                         }                          }
                         sk_X509_push(sk, cert);                          sk_X509_push(sk, cert);
   
Line 1731  static STACK_OF(X509) * php_array_to_X509_sk(zval ** z Line 1875  static STACK_OF(X509) * php_array_to_X509_sk(zval ** z
         } else {          } else {
                 /* a single certificate */                  /* a single certificate */
                 cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC);                  cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC);
                
                 if (cert == NULL) {                  if (cert == NULL) {
                         goto clean_exit;                          goto clean_exit;
                 }                  }
Line 1768  PHP_FUNCTION(openssl_pkcs12_export_to_file) Line 1912  PHP_FUNCTION(openssl_pkcs12_export_to_file)
         zval ** item;          zval ** item;
         STACK_OF(X509) *ca = NULL;          STACK_OF(X509) *ca = NULL;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zszs|a", &zcert, &filename, &filename_len, &zpkey, &pass, &pass_len, &args) == FAILURE)        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zpzs|a", &zcert, &filename, &filename_len, &zpkey, &pass, &pass_len, &args) == FAILURE)
                 return;                  return;
   
         RETVAL_FALSE;          RETVAL_FALSE;
   
         if (strlen(filename) != filename_len) {  
                 return;  
         }  
           
         cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);          cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
         if (cert == NULL) {          if (cert == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
Line 1791  PHP_FUNCTION(openssl_pkcs12_export_to_file) Line 1931  PHP_FUNCTION(openssl_pkcs12_export_to_file)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to cert");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to cert");
                 goto cleanup;                  goto cleanup;
         }          }
        if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
                 goto cleanup;                  goto cleanup;
         }          }
   
Line 1812  PHP_FUNCTION(openssl_pkcs12_export_to_file) Line 1952  PHP_FUNCTION(openssl_pkcs12_export_to_file)
   
         p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);          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) {          if (bio_out) {
                
                 i2d_PKCS12_bio(bio_out, p12);                  i2d_PKCS12_bio(bio_out, p12);
   
                 RETVAL_TRUE;                  RETVAL_TRUE;
Line 1825  PHP_FUNCTION(openssl_pkcs12_export_to_file) Line 1965  PHP_FUNCTION(openssl_pkcs12_export_to_file)
         BIO_free(bio_out);          BIO_free(bio_out);
         PKCS12_free(p12);          PKCS12_free(p12);
         php_sk_X509_free(ca);          php_sk_X509_free(ca);
        
 cleanup:  cleanup:
   
         if (keyresource == -1 && priv_key) {          if (keyresource == -1 && priv_key) {
                 EVP_PKEY_free(priv_key);                  EVP_PKEY_free(priv_key);
         }          }
        if (certresource == -1 && cert) {         if (certresource == -1 && cert) {
                 X509_free(cert);                  X509_free(cert);
         }          }
 }  }
Line 1857  PHP_FUNCTION(openssl_pkcs12_export) Line 1997  PHP_FUNCTION(openssl_pkcs12_export)
                 return;                  return;
   
         RETVAL_FALSE;          RETVAL_FALSE;
        
         cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);          cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
         if (cert == NULL) {          if (cert == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
Line 1880  PHP_FUNCTION(openssl_pkcs12_export) Line 2020  PHP_FUNCTION(openssl_pkcs12_export)
         if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)          if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
                 ca = php_array_to_X509_sk(item TSRMLS_CC);                  ca = php_array_to_X509_sk(item TSRMLS_CC);
         /* end parse extra config */          /* end parse extra config */
        
         p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);          p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
   
         bio_out = BIO_new(BIO_s_mem());          bio_out = BIO_new(BIO_s_mem());
Line 1897  PHP_FUNCTION(openssl_pkcs12_export) Line 2037  PHP_FUNCTION(openssl_pkcs12_export)
         BIO_free(bio_out);          BIO_free(bio_out);
         PKCS12_free(p12);          PKCS12_free(p12);
         php_sk_X509_free(ca);          php_sk_X509_free(ca);
        
 cleanup:  cleanup:
   
         if (keyresource == -1 && priv_key) {          if (keyresource == -1 && priv_key) {
                 EVP_PKEY_free(priv_key);                  EVP_PKEY_free(priv_key);
         }          }
        if (certresource == -1 && cert) {         if (certresource == -1 && cert) {
                 X509_free(cert);                  X509_free(cert);
         }          }
 }  }
Line 1927  PHP_FUNCTION(openssl_pkcs12_read) Line 2067  PHP_FUNCTION(openssl_pkcs12_read)
                 return;                  return;
   
         RETVAL_FALSE;          RETVAL_FALSE;
        
         bio_in = BIO_new(BIO_s_mem());          bio_in = BIO_new(BIO_s_mem());
        
         if(!BIO_write(bio_in, zp12, zp12_len))          if(!BIO_write(bio_in, zp12, zp12_len))
                 goto cleanup;                  goto cleanup;
        
         if(d2i_PKCS12_bio(bio_in, &p12)) {          if(d2i_PKCS12_bio(bio_in, &p12)) {
                 if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {                  if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
                         BIO * bio_out;                          BIO * bio_out;
Line 1962  PHP_FUNCTION(openssl_pkcs12_read) Line 2102  PHP_FUNCTION(openssl_pkcs12_read)
   
                         MAKE_STD_ZVAL(zextracerts);                          MAKE_STD_ZVAL(zextracerts);
                         array_init(zextracerts);                          array_init(zextracerts);
                        
                         for (i=0;;i++) {                          for (i=0;;i++) {
                                 zval * zextracert;                                  zval * zextracert;
                                 X509* aCA = sk_X509_pop(ca);                                  X509* aCA = sk_X509_pop(ca);
                                 if (!aCA) break;                                  if (!aCA) break;
                                
                                 bio_out = BIO_new(BIO_s_mem());                                  bio_out = BIO_new(BIO_s_mem());
                                 if (PEM_write_bio_X509(bio_out, aCA)) {                                  if (PEM_write_bio_X509(bio_out, aCA)) {
                                         BUF_MEM *bio_buf;                                          BUF_MEM *bio_buf;
Line 1975  PHP_FUNCTION(openssl_pkcs12_read) Line 2115  PHP_FUNCTION(openssl_pkcs12_read)
                                         MAKE_STD_ZVAL(zextracert);                                          MAKE_STD_ZVAL(zextracert);
                                         ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1);                                          ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1);
                                         add_index_zval(zextracerts, i, zextracert);                                          add_index_zval(zextracerts, i, zextracert);
                                        
                                 }                                  }
                                 BIO_free(bio_out);                                  BIO_free(bio_out);
   
Line 1987  PHP_FUNCTION(openssl_pkcs12_read) Line 2127  PHP_FUNCTION(openssl_pkcs12_read)
                         } else {                          } else {
                                 zval_dtor(zextracerts);                                  zval_dtor(zextracerts);
                         }                          }
                        
                         RETVAL_TRUE;                          RETVAL_TRUE;
                        
                         PKCS12_free(p12);                          PKCS12_free(p12);
                 }                  }
         }          }
        
   cleanup:    cleanup:
         if (bio_in) {          if (bio_in) {
                 BIO_free(bio_in);                  BIO_free(bio_in);
Line 2001  PHP_FUNCTION(openssl_pkcs12_read) Line 2141  PHP_FUNCTION(openssl_pkcs12_read)
         if (pkey) {          if (pkey) {
                 EVP_PKEY_free(pkey);                  EVP_PKEY_free(pkey);
         }          }
        if (cert) {         if (cert) {
                 X509_free(cert);                  X509_free(cert);
         }          }
 }  }
Line 2020  static int php_openssl_make_REQ(struct php_x509_reques Line 2160  static int php_openssl_make_REQ(struct php_x509_reques
                 return FAILURE;                  return FAILURE;
         }          }
         dn_sk = CONF_get_section(req->req_config, dn_sect);          dn_sk = CONF_get_section(req->req_config, dn_sect);
        if (dn_sk == NULL) {         if (dn_sk == NULL) {
                 return FAILURE;                  return FAILURE;
         }          }
         attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");          attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
Line 2040  static int php_openssl_make_REQ(struct php_x509_reques Line 2180  static int php_openssl_make_REQ(struct php_x509_reques
                 X509_NAME * subj;                  X509_NAME * subj;
                 HashPosition hpos;                  HashPosition hpos;
                 zval ** item;                  zval ** item;
                
                 subj = X509_REQ_get_subject_name(csr);                  subj = X509_REQ_get_subject_name(csr);
                 /* apply values from the dn hash */                  /* apply values from the dn hash */
                 zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos);                  zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos);
                 while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) {                  while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) {
                        char * strindex = NULL;                         char * strindex = NULL;
                         uint strindexlen = 0;                          uint strindexlen = 0;
                         ulong intindex;                          ulong intindex;
                        
                         zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos);                          zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos);
   
                         convert_to_string_ex(item);                          convert_to_string_ex(item);
Line 2058  static int php_openssl_make_REQ(struct php_x509_reques Line 2198  static int php_openssl_make_REQ(struct php_x509_reques
   
                                 nid = OBJ_txt2nid(strindex);                                  nid = OBJ_txt2nid(strindex);
                                 if (nid != NID_undef) {                                  if (nid != NID_undef) {
                                        if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_ASC,                                         if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
                                                                 (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0))                                                                  (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0))
                                         {                                          {
                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "dn: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_PP(item));                                                php_error_docref(NULL TSRMLS_CC, E_WARNING,
                                                         "dn: add_entry_by_NID %d -> %s (failed; check error"
                                                         " queue and value of string_mask OpenSSL option "
                                                         "if illegal characters are reported)",
                                                         nid, Z_STRVAL_PP(item));
                                                 return FAILURE;                                                  return FAILURE;
                                         }                                          }
                                 } else {                                  } else {
Line 2075  static int php_openssl_make_REQ(struct php_x509_reques Line 2219  static int php_openssl_make_REQ(struct php_x509_reques
                 for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {                  for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
                         int len;                          int len;
                         char buffer[200 + 1]; /*200 + \0 !*/                          char buffer[200 + 1]; /*200 + \0 !*/
                        
                         v = sk_CONF_VALUE_value(dn_sk, i);                          v = sk_CONF_VALUE_value(dn_sk, i);
                         type = v->name;                          type = v->name;
                        
                         len = strlen(type);                          len = strlen(type);
                         if (len < sizeof("_default")) {                          if (len < sizeof("_default")) {
                                 continue;                                  continue;
Line 2093  static int php_openssl_make_REQ(struct php_x509_reques Line 2237  static int php_openssl_make_REQ(struct php_x509_reques
                         memcpy(buffer, type, len);                          memcpy(buffer, type, len);
                         buffer[len] = '\0';                          buffer[len] = '\0';
                         type = buffer;                          type = buffer;
                
                         /* Skip past any leading X. X: X, etc to allow for multiple                          /* Skip past any leading X. X: X, etc to allow for multiple
                          * instances */                           * instances */
                         for (str = type; *str; str++) {                          for (str = type; *str; str++) {
Line 2110  static int php_openssl_make_REQ(struct php_x509_reques Line 2254  static int php_openssl_make_REQ(struct php_x509_reques
                         if (X509_NAME_get_index_by_NID(subj, nid, -1) >= 0) {                          if (X509_NAME_get_index_by_NID(subj, nid, -1) >= 0) {
                                 continue;                                  continue;
                         }                          }
                        if (!X509_NAME_add_entry_by_txt(subj, type, MBSTRING_ASC, (unsigned char*)v->value, -1, -1, 0)) {                        if (!X509_NAME_add_entry_by_txt(subj, type, MBSTRING_UTF8, (unsigned char*)v->value, -1, -1, 0)) {
                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_entry_by_txt %s -> %s (failed)", type, v->value);                                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_entry_by_txt %s -> %s (failed)", type, v->value);
                                 return FAILURE;                                  return FAILURE;
                         }                          }
Line 2134  static int php_openssl_make_REQ(struct php_x509_reques Line 2278  static int php_openssl_make_REQ(struct php_x509_reques
   
                                         nid = OBJ_txt2nid(strindex);                                          nid = OBJ_txt2nid(strindex);
                                         if (nid != NID_undef) {                                          if (nid != NID_undef) {
                                                if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_ASC, (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0)) {                                                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, "attribs: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_PP(item));                                                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "attribs: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_PP(item));
                                                         return FAILURE;                                                          return FAILURE;
                                                 }                                                  }
Line 2151  static int php_openssl_make_REQ(struct php_x509_reques Line 2295  static int php_openssl_make_REQ(struct php_x509_reques
                                 if (X509_REQ_get_attr_by_NID(csr, nid, -1) >= 0) {                                  if (X509_REQ_get_attr_by_NID(csr, nid, -1) >= 0) {
                                         continue;                                          continue;
                                 }                                  }
                                if (!X509_REQ_add1_attr_by_txt(csr, v->name, MBSTRING_ASC, (unsigned char*)v->value, -1)) {                                if (!X509_REQ_add1_attr_by_txt(csr, v->name, MBSTRING_UTF8, (unsigned char*)v->value, -1)) {
                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "add1_attr_by_txt %s -> %s (failed)", v->name, v->value);                                        php_error_docref(NULL TSRMLS_CC, E_WARNING,
                                                 "add1_attr_by_txt %s -> %s (failed; check error queue "
                                                 "and value of string_mask OpenSSL option if illegal "
                                                 "characters are reported)",
                                                 v->name, v->value);
                                         return FAILURE;                                          return FAILURE;
                                 }                                  }
                         }                          }
Line 2170  static X509_REQ * php_openssl_csr_from_zval(zval ** va Line 2318  static X509_REQ * php_openssl_csr_from_zval(zval ** va
         X509_REQ * csr = NULL;          X509_REQ * csr = NULL;
         char * filename = NULL;          char * filename = NULL;
         BIO * in;          BIO * in;
        
         if (resourceval) {          if (resourceval) {
                 *resourceval = -1;                  *resourceval = -1;
         }          }
Line 2194  static X509_REQ * php_openssl_csr_from_zval(zval ** va Line 2342  static X509_REQ * php_openssl_csr_from_zval(zval ** va
                 filename = Z_STRVAL_PP(val) + (sizeof("file://") - 1);                  filename = Z_STRVAL_PP(val) + (sizeof("file://") - 1);
         }          }
         if (filename) {          if (filename) {
                if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {                if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
                         return NULL;                          return NULL;
                 }                  }
                 in = BIO_new_file(filename, "r");                  in = BIO_new_file(filename, "r");
Line 2219  PHP_FUNCTION(openssl_csr_export_to_file) Line 2367  PHP_FUNCTION(openssl_csr_export_to_file)
         BIO * bio_out;          BIO * bio_out;
         long csr_resource;          long csr_resource;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", &zcsr, &filename, &filename_len, &notext) == FAILURE) {        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp|b", &zcsr, &filename, &filename_len, &notext) == FAILURE) {
                 return;                  return;
         }          }
         RETVAL_FALSE;          RETVAL_FALSE;
   
         if (strlen(filename) != filename_len) {  
                 return;  
         }  
   
         csr = php_openssl_csr_from_zval(&zcsr, 0, &csr_resource TSRMLS_CC);          csr = php_openssl_csr_from_zval(&zcsr, 0, &csr_resource TSRMLS_CC);
         if (csr == NULL) {          if (csr == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
                 return;                  return;
         }          }
   
        if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
                 return;                  return;
         }          }
   
Line 2315  PHP_FUNCTION(openssl_csr_sign) Line 2459  PHP_FUNCTION(openssl_csr_sign)
         long csr_resource, certresource = 0, keyresource = -1;          long csr_resource, certresource = 0, keyresource = -1;
         int i;          int i;
         struct php_x509_request req;          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)          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ!Zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
                 return;                  return;
   
         RETVAL_FALSE;          RETVAL_FALSE;
         PHP_SSL_REQ_INIT(&req);          PHP_SSL_REQ_INIT(&req);
        
         csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);          csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
         if (csr == NULL) {          if (csr == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
Line 2343  PHP_FUNCTION(openssl_csr_sign) Line 2487  PHP_FUNCTION(openssl_csr_sign)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");
                 goto cleanup;                  goto cleanup;
         }          }
        
         if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) {          if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) {
                 goto cleanup;                  goto cleanup;
         }          }
Line 2363  PHP_FUNCTION(openssl_csr_sign) Line 2507  PHP_FUNCTION(openssl_csr_sign)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");
                 goto cleanup;                  goto cleanup;
         }          }
        
         /* Now we can get on with it */          /* Now we can get on with it */
        
         new_cert = X509_new();          new_cert = X509_new();
         if (new_cert == NULL) {          if (new_cert == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");
Line 2376  PHP_FUNCTION(openssl_csr_sign) Line 2520  PHP_FUNCTION(openssl_csr_sign)
                 goto cleanup;                  goto cleanup;
   
         ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);          ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
        
         X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));          X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
   
         if (cert == NULL) {          if (cert == NULL) {
Line 2393  PHP_FUNCTION(openssl_csr_sign) Line 2537  PHP_FUNCTION(openssl_csr_sign)
         }          }
         if (req.extensions_section) {          if (req.extensions_section) {
                 X509V3_CTX ctx;                  X509V3_CTX ctx;
                
                 X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);                  X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);
                 X509V3_set_conf_lhash(&ctx, req.req_config);                  X509V3_set_conf_lhash(&ctx, req.req_config);
                 if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) {                  if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) {
Line 2406  PHP_FUNCTION(openssl_csr_sign) Line 2550  PHP_FUNCTION(openssl_csr_sign)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");
                 goto cleanup;                  goto cleanup;
         }          }
        
         /* Succeeded; lets return the cert */          /* Succeeded; lets return the cert */
        RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509));        RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509 TSRMLS_CC));
         new_cert = NULL;          new_cert = NULL;
        
 cleanup:  cleanup:
   
         if (cert == new_cert) {          if (cert == new_cert) {
Line 2427  cleanup: Line 2571  cleanup:
         if (csr_resource == -1 && csr) {          if (csr_resource == -1 && csr) {
                 X509_REQ_free(csr);                  X509_REQ_free(csr);
         }          }
        if (certresource == -1 && cert) {         if (certresource == -1 && cert) {
                 X509_free(cert);                  X509_free(cert);
         }          }
         if (new_cert) {          if (new_cert) {
Line 2446  PHP_FUNCTION(openssl_csr_new) Line 2590  PHP_FUNCTION(openssl_csr_new)
         X509_REQ * csr = NULL;          X509_REQ * csr = NULL;
         int we_made_the_key = 1;          int we_made_the_key = 1;
         long key_resource;          long key_resource;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
                 return;                  return;
         }          }
         RETVAL_FALSE;          RETVAL_FALSE;
        
         PHP_SSL_REQ_INIT(&req);          PHP_SSL_REQ_INIT(&req);
   
         if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {          if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
Line 2483  PHP_FUNCTION(openssl_csr_new) Line 2627  PHP_FUNCTION(openssl_csr_new)
                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);                                                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);
                                         } else {                                          } else {
                                                 RETVAL_TRUE;                                                  RETVAL_TRUE;
                                                
                                                 if (X509_REQ_sign(csr, req.priv_key, req.digest)) {                                                  if (X509_REQ_sign(csr, req.priv_key, req.digest)) {
                                                        RETVAL_RESOURCE(zend_list_insert(csr, le_csr));                                                        RETVAL_RESOURCE(zend_list_insert(csr, le_csr TSRMLS_CC));
                                                        csr = NULL;                                                                             csr = NULL;
                                                 } else {                                                  } else {
                                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");                                                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");
                                                 }                                                  }
Line 2494  PHP_FUNCTION(openssl_csr_new) Line 2638  PHP_FUNCTION(openssl_csr_new)
                                                 if (we_made_the_key) {                                                  if (we_made_the_key) {
                                                         /* and a resource for the private key */                                                          /* and a resource for the private key */
                                                         zval_dtor(out_pkey);                                                          zval_dtor(out_pkey);
                                                        ZVAL_RESOURCE(out_pkey, zend_list_insert(req.priv_key, le_key));                                                        ZVAL_RESOURCE(out_pkey, zend_list_insert(req.priv_key, le_key TSRMLS_CC));
                                                         req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */                                                          req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */
                                                 } else if (key_resource != -1) {                                                  } else if (key_resource != -1) {
                                                         req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */                                                          req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */
Line 2567  PHP_FUNCTION(openssl_csr_get_public_key) Line 2711  PHP_FUNCTION(openssl_csr_get_public_key)
         }          }
   
         tpubkey=X509_REQ_get_pubkey(csr);          tpubkey=X509_REQ_get_pubkey(csr);
        RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key));        RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key TSRMLS_CC));
         return;          return;
 }  }
 /* }}} */  /* }}} */
Line 2611  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va Line 2755  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va
         }          }
         if (Z_TYPE_PP(val) == IS_ARRAY) {          if (Z_TYPE_PP(val) == IS_ARRAY) {
                 zval ** zphrase;                  zval ** zphrase;
                
                 /* get passphrase */                  /* get passphrase */
   
                 if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) {                  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)");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
                         return NULL;                          return NULL;
                 }                  }
                
                 if (Z_TYPE_PP(zphrase) == IS_STRING) {                  if (Z_TYPE_PP(zphrase) == IS_STRING) {
                         passphrase = Z_STRVAL_PP(zphrase);                          passphrase = Z_STRVAL_PP(zphrase);
                 } else {                  } else {
Line 2643  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va Line 2787  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va
                 if (!what) {                  if (!what) {
                         TMP_CLEAN;                          TMP_CLEAN;
                 }                  }
                if (resourceval) {                 if (resourceval) {
                         *resourceval = Z_LVAL_PP(val);                          *resourceval = Z_LVAL_PP(val);
                 }                  }
                 if (type == le_x509) {                  if (type == le_x509) {
Line 2677  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va Line 2821  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va
                 }                  }
         } else {          } else {
                 /* force it to be a string and check if it refers to a file */                  /* 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                 /* passing non string values leaks, object uses toString, it returns NULL
                 * See bug38255.phpt                  * See bug38255.phpt
                  */                   */
                 if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {                  if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {
                         TMP_CLEAN;                          TMP_CLEAN;
Line 2712  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va Line 2856  static EVP_PKEY * php_openssl_evp_from_zval(zval ** va
                         BIO *in;                          BIO *in;
   
                         if (filename) {                          if (filename) {
                                if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {                                if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
                                         TMP_CLEAN;                                          TMP_CLEAN;
                                 }                                  }
                                 in = BIO_new_file(filename, "r");                                  in = BIO_new_file(filename, "r");
Line 2752  static EVP_PKEY * php_openssl_generate_private_key(str Line 2896  static EVP_PKEY * php_openssl_generate_private_key(str
         char * randfile = NULL;          char * randfile = NULL;
         int egdsocket, seeded;          int egdsocket, seeded;
         EVP_PKEY * return_val = NULL;          EVP_PKEY * return_val = NULL;
        
         if (req->priv_key_bits < MIN_KEY_LENGTH) {          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",                  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);                                  MIN_KEY_LENGTH, req->priv_key_bits);
Line 2760  static EVP_PKEY * php_openssl_generate_private_key(str Line 2904  static EVP_PKEY * php_openssl_generate_private_key(str
         }          }
   
         randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");          randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
        php_openssl_load_rand_file(randfile, &egdsocket, &seeded);        php_openssl_load_rand_file(randfile, &egdsocket, &seeded TSRMLS_CC);
        
         if ((req->priv_key = EVP_PKEY_new()) != NULL) {          if ((req->priv_key = EVP_PKEY_new()) != NULL) {
                 switch(req->priv_key_type) {                  switch(req->priv_key_type) {
                         case OPENSSL_KEYTYPE_RSA:                          case OPENSSL_KEYTYPE_RSA:
Line 2811  static EVP_PKEY * php_openssl_generate_private_key(str Line 2955  static EVP_PKEY * php_openssl_generate_private_key(str
         }          }
   
         php_openssl_write_rand_file(randfile, egdsocket, seeded);          php_openssl_write_rand_file(randfile, egdsocket, seeded);
        
         if (return_val == NULL) {          if (return_val == NULL) {
                 EVP_PKEY_free(req->priv_key);                  EVP_PKEY_free(req->priv_key);
                 req->priv_key = NULL;                  req->priv_key = NULL;
                 return NULL;                  return NULL;
         }          }
        
         return return_val;          return return_val;
 }  }
 /* }}} */  /* }}} */
Line 2846  static int php_openssl_is_private_key(EVP_PKEY* pkey T Line 2990  static int php_openssl_is_private_key(EVP_PKEY* pkey T
                 case EVP_PKEY_DSA4:                  case EVP_PKEY_DSA4:
                         assert(pkey->pkey.dsa != NULL);                          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;                                  return 0;
                         }                          }
                         break;                          break;
Line 2921  PHP_FUNCTION(openssl_pkey_new) Line 3065  PHP_FUNCTION(openssl_pkey_new)
                                         OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, iqmp);                                          OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, iqmp);
                                         if (rsa->n && rsa->d) {                                          if (rsa->n && rsa->d) {
                                                 if (EVP_PKEY_assign_RSA(pkey, rsa)) {                                                  if (EVP_PKEY_assign_RSA(pkey, rsa)) {
                                                        RETURN_RESOURCE(zend_list_insert(pkey, le_key));                                                        RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
                                                 }                                                  }
                                         }                                          }
                                         RSA_free(rsa);                                          RSA_free(rsa);
Line 2945  PHP_FUNCTION(openssl_pkey_new) Line 3089  PHP_FUNCTION(openssl_pkey_new)
                                                         DSA_generate_key(dsa);                                                          DSA_generate_key(dsa);
                                                 }                                                  }
                                                 if (EVP_PKEY_assign_DSA(pkey, dsa)) {                                                  if (EVP_PKEY_assign_DSA(pkey, dsa)) {
                                                        RETURN_RESOURCE(zend_list_insert(pkey, le_key));                                                        RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
                                                 }                                                  }
                                         }                                          }
                                         DSA_free(dsa);                                          DSA_free(dsa);
Line 2968  PHP_FUNCTION(openssl_pkey_new) Line 3112  PHP_FUNCTION(openssl_pkey_new)
                                                         DH_generate_key(dh);                                                          DH_generate_key(dh);
                                                 }                                                  }
                                                 if (EVP_PKEY_assign_DH(pkey, dh)) {                                                  if (EVP_PKEY_assign_DH(pkey, dh)) {
                                                        RETURN_RESOURCE(zend_list_insert(pkey, le_key));                                                        RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
                                                 }                                                  }
                                         }                                          }
                                         DH_free(dh);                                          DH_free(dh);
Line 2977  PHP_FUNCTION(openssl_pkey_new) Line 3121  PHP_FUNCTION(openssl_pkey_new)
                         }                          }
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
        }         }
   
         PHP_SSL_REQ_INIT(&req);          PHP_SSL_REQ_INIT(&req);
   
Line 2985  PHP_FUNCTION(openssl_pkey_new) Line 3129  PHP_FUNCTION(openssl_pkey_new)
         {          {
                 if (php_openssl_generate_private_key(&req TSRMLS_CC)) {                  if (php_openssl_generate_private_key(&req TSRMLS_CC)) {
                         /* pass back a key resource */                          /* pass back a key resource */
                        RETVAL_RESOURCE(zend_list_insert(req.priv_key, le_key));                        RETVAL_RESOURCE(zend_list_insert(req.priv_key, le_key TSRMLS_CC));
                         /* make sure the cleanup code doesn't zap it! */                          /* make sure the cleanup code doesn't zap it! */
                         req.priv_key = NULL;                          req.priv_key = NULL;
                 }                  }
Line 3006  PHP_FUNCTION(openssl_pkey_export_to_file) Line 3150  PHP_FUNCTION(openssl_pkey_export_to_file)
         EVP_PKEY * key;          EVP_PKEY * key;
         BIO * bio_out = NULL;          BIO * bio_out = NULL;
         const EVP_CIPHER * cipher;          const EVP_CIPHER * cipher;
        
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
                 return;                  return;
         }          }
         RETVAL_FALSE;          RETVAL_FALSE;
   
         if (strlen(filename) != filename_len) {  
                 return;  
         }  
   
         key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource TSRMLS_CC);          key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource TSRMLS_CC);
   
         if (key == NULL) {          if (key == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
        if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
         PHP_SSL_REQ_INIT(&req);          PHP_SSL_REQ_INIT(&req);
   
         if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {          if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
                 bio_out = BIO_new_file(filename, "w");                  bio_out = BIO_new_file(filename, "w");
   
                 if (passphrase && req.priv_key_encrypt) {                  if (passphrase && req.priv_key_encrypt) {
                        cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();                        if (req.priv_key_encrypt_cipher) {
                                 cipher = req.priv_key_encrypt_cipher;
                         } else {
                                 cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
                         }
                 } else {                  } else {
                         cipher = NULL;                          cipher = NULL;
                 }                  }
Line 3065  PHP_FUNCTION(openssl_pkey_export) Line 3209  PHP_FUNCTION(openssl_pkey_export)
         EVP_PKEY * key;          EVP_PKEY * key;
         BIO * bio_out = NULL;          BIO * bio_out = NULL;
         const EVP_CIPHER * cipher;          const EVP_CIPHER * cipher;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
                 return;                  return;
         }          }
Line 3077  PHP_FUNCTION(openssl_pkey_export) Line 3221  PHP_FUNCTION(openssl_pkey_export)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
         PHP_SSL_REQ_INIT(&req);          PHP_SSL_REQ_INIT(&req);
   
         if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {          if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
                 bio_out = BIO_new(BIO_s_mem());                  bio_out = BIO_new(BIO_s_mem());
   
                 if (passphrase && req.priv_key_encrypt) {                  if (passphrase && req.priv_key_encrypt) {
                        cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();                        if (req.priv_key_encrypt_cipher) {
                                 cipher = req.priv_key_encrypt_cipher;
                         } else {
                                 cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
                         }
                 } else {                  } else {
                         cipher = NULL;                          cipher = NULL;
                 }                  }
Line 3128  PHP_FUNCTION(openssl_pkey_get_public) Line 3276  PHP_FUNCTION(openssl_pkey_get_public)
         if (pkey == NULL) {          if (pkey == NULL) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
           zend_list_addref(Z_LVAL_P(return_value));
 }  }
 /* }}} */  /* }}} */
   
Line 3164  PHP_FUNCTION(openssl_pkey_get_private) Line 3313  PHP_FUNCTION(openssl_pkey_get_private)
         if (pkey == NULL) {          if (pkey == NULL) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
           zend_list_addref(Z_LVAL_P(return_value));
 }  }
   
 /* }}} */  /* }}} */
Line 3193  PHP_FUNCTION(openssl_pkey_get_details) Line 3343  PHP_FUNCTION(openssl_pkey_get_details)
         array_init(return_value);          array_init(return_value);
         add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey));          add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey));
         add_assoc_stringl(return_value, "key", pbio, pbio_len, 1);          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           * See the enum at the top of this file
          */           */
         switch (EVP_PKEY_type(pkey->type)) {          switch (EVP_PKEY_type(pkey->type)) {
Line 3217  PHP_FUNCTION(openssl_pkey_get_details) Line 3367  PHP_FUNCTION(openssl_pkey_get_details)
                                 add_assoc_zval(return_value, "rsa", rsa);                                  add_assoc_zval(return_value, "rsa", rsa);
                         }                          }
   
                        break;                          break;
                 case EVP_PKEY_DSA:                  case EVP_PKEY_DSA:
                 case EVP_PKEY_DSA2:                  case EVP_PKEY_DSA2:
                 case EVP_PKEY_DSA3:                  case EVP_PKEY_DSA3:
Line 3238  PHP_FUNCTION(openssl_pkey_get_details) Line 3388  PHP_FUNCTION(openssl_pkey_get_details)
                         }                          }
                         break;                          break;
                 case EVP_PKEY_DH:                  case EVP_PKEY_DH:
                        
                         ktype = OPENSSL_KEYTYPE_DH;                          ktype = OPENSSL_KEYTYPE_DH;
   
                         if (pkey->pkey.dh != NULL) {                          if (pkey->pkey.dh != NULL) {
Line 3254  PHP_FUNCTION(openssl_pkey_get_details) Line 3404  PHP_FUNCTION(openssl_pkey_get_details)
                         }                          }
   
                         break;                          break;
#ifdef EVP_PKEY_EC #ifdef EVP_PKEY_EC
                 case EVP_PKEY_EC:                  case EVP_PKEY_EC:
                         ktype = OPENSSL_KEYTYPE_EC;                          ktype = OPENSSL_KEYTYPE_EC;
                         break;                          break;
Line 3288  PHP_FUNCTION(openssl_pkcs7_verify) Line 3438  PHP_FUNCTION(openssl_pkcs7_verify)
         char * extracerts = NULL; int extracerts_len = 0;          char * extracerts = NULL; int extracerts_len = 0;
         char * signersfilename = NULL; int signersfilename_len = 0;          char * signersfilename = NULL; int signersfilename_len = 0;
         char * datafilename = NULL; int datafilename_len = 0;          char * datafilename = NULL; int datafilename_len = 0;
        
         RETVAL_LONG(-1);          RETVAL_LONG(-1);
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|sass", &filename, &filename_len,        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pl|papp", &filename, &filename_len,
                                 &flags, &signersfilename, &signersfilename_len, &cainfo,                                  &flags, &signersfilename, &signersfilename_len, &cainfo,
                                 &extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {                                  &extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {
                 return;                  return;
         }          }
        
         if (extracerts) {          if (extracerts) {
                 others = load_all_certs_from_file(extracerts);                  others = load_all_certs_from_file(extracerts);
                 if (others == NULL) {                  if (others == NULL) {
Line 3311  PHP_FUNCTION(openssl_pkcs7_verify) Line 3461  PHP_FUNCTION(openssl_pkcs7_verify)
         if (!store) {          if (!store) {
                 goto clean_exit;                  goto clean_exit;
         }          }
        if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
                 goto clean_exit;                  goto clean_exit;
         }          }
   
Line 3329  PHP_FUNCTION(openssl_pkcs7_verify) Line 3479  PHP_FUNCTION(openssl_pkcs7_verify)
   
         if (datafilename) {          if (datafilename) {
   
                if (php_openssl_safe_mode_chk(datafilename TSRMLS_CC)) {                if (php_openssl_open_base_dir_chk(datafilename TSRMLS_CC)) {
                         goto clean_exit;                          goto clean_exit;
                 }                  }
   
Line 3348  PHP_FUNCTION(openssl_pkcs7_verify) Line 3498  PHP_FUNCTION(openssl_pkcs7_verify)
   
                 if (signersfilename) {                  if (signersfilename) {
                         BIO *certout;                          BIO *certout;
                
                        if (php_openssl_safe_mode_chk(signersfilename TSRMLS_CC)) {                        if (php_openssl_open_base_dir_chk(signersfilename TSRMLS_CC)) {
                                 goto clean_exit;                                  goto clean_exit;
                         }                          }
                
                         certout = BIO_new_file(signersfilename, "w");                          certout = BIO_new_file(signersfilename, "w");
                         if (certout) {                          if (certout) {
                                 int i;                                  int i;
Line 3401  PHP_FUNCTION(openssl_pkcs7_encrypt) Line 3551  PHP_FUNCTION(openssl_pkcs7_encrypt)
         char * strindex;          char * strindex;
         char * infilename = NULL;       int infilename_len;          char * infilename = NULL;       int infilename_len;
         char * outfilename = NULL;      int outfilename_len;          char * outfilename = NULL;      int outfilename_len;
        
         RETVAL_FALSE;          RETVAL_FALSE;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZa!|ll", &infilename, &infilename_len,        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZa!|ll", &infilename, &infilename_len,
                                 &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)                                  &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
                 return;                  return;
   
         if (strlen(infilename) != infilename_len) {  
                 return;  
         }  
   
        if (strlen(outfilename) != outfilename_len) {        if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
                 return;                  return;
         }          }
   
         if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {  
                 return;  
         }  
   
         infile = BIO_new_file(infilename, "r");          infile = BIO_new_file(infilename, "r");
         if (infile == NULL) {          if (infile == NULL) {
                 goto clean_exit;                  goto clean_exit;
         }          }
   
         outfile = BIO_new_file(outfilename, "w");          outfile = BIO_new_file(outfilename, "w");
        if (outfile == NULL) {         if (outfile == NULL) {
                 goto clean_exit;                  goto clean_exit;
         }          }
   
Line 3547  PHP_FUNCTION(openssl_pkcs7_sign) Line 3690  PHP_FUNCTION(openssl_pkcs7_sign)
         char * outfilename;     int outfilename_len;          char * outfilename;     int outfilename_len;
         char * extracertsfilename = NULL; int extracertsfilename_len;          char * extracertsfilename = NULL; int extracertsfilename_len;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZZa!|ls",        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZZa!|lp",
                                 &infilename, &infilename_len, &outfilename, &outfilename_len,                                  &infilename, &infilename_len, &outfilename, &outfilename_len,
                                 &zcert, &zprivkey, &zheaders, &flags, &extracertsfilename,                                  &zcert, &zprivkey, &zheaders, &flags, &extracertsfilename,
                                 &extracertsfilename_len) == FAILURE) {                                  &extracertsfilename_len) == FAILURE) {
                 return;                  return;
         }          }
   
         RETVAL_FALSE;          RETVAL_FALSE;
   
         if (strlen(infilename) != infilename_len) {  
                 return;  
         }  
   
         if (strlen(outfilename) != outfilename_len) {  
                 return;  
         }  
   
         if (extracertsfilename) {          if (extracertsfilename) {
                 others = load_all_certs_from_file(extracertsfilename);                  others = load_all_certs_from_file(extracertsfilename);
                if (others == NULL) {                 if (others == NULL) {
                         goto clean_exit;                          goto clean_exit;
                 }                  }
         }          }
Line 3582  PHP_FUNCTION(openssl_pkcs7_sign) Line 3718  PHP_FUNCTION(openssl_pkcs7_sign)
                 goto clean_exit;                  goto clean_exit;
         }          }
   
        if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
                 goto clean_exit;                  goto clean_exit;
         }          }
   
Line 3658  PHP_FUNCTION(openssl_pkcs7_decrypt) Line 3794  PHP_FUNCTION(openssl_pkcs7_decrypt)
         char * infilename;      int infilename_len;          char * infilename;      int infilename_len;
         char * outfilename;     int outfilename_len;          char * outfilename;     int outfilename_len;
   
        RETVAL_FALSE;        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZ|Z", &infilename, &infilename_len,
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|Z", &infilename, &infilename_len, 
                                 &outfilename, &outfilename_len, &recipcert, &recipkey) == FAILURE) {                                  &outfilename, &outfilename_len, &recipcert, &recipkey) == FAILURE) {
                 return;                  return;
         }          }
   
        if (strlen(infilename) != infilename_len) {        RETVAL_FALSE;
                return; 
        } 
   
         if (strlen(outfilename) != outfilename_len) {  
                 return;  
         }  
   
         cert = php_openssl_x509_from_zval(recipcert, 0, &certresval TSRMLS_CC);          cert = php_openssl_x509_from_zval(recipcert, 0, &certresval TSRMLS_CC);
         if (cert == NULL) {          if (cert == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to coerce parameter 3 to x509 cert");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to coerce parameter 3 to x509 cert");
Line 3684  PHP_FUNCTION(openssl_pkcs7_decrypt) Line 3812  PHP_FUNCTION(openssl_pkcs7_decrypt)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key");
                 goto clean_exit;                  goto clean_exit;
         }          }
        
        if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {        if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
                 goto clean_exit;                  goto clean_exit;
         }          }
   
Line 3703  PHP_FUNCTION(openssl_pkcs7_decrypt) Line 3831  PHP_FUNCTION(openssl_pkcs7_decrypt)
         if (p7 == NULL) {          if (p7 == NULL) {
                 goto clean_exit;                  goto clean_exit;
         }          }
        if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {         if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
                 RETVAL_TRUE;                  RETVAL_TRUE;
         }          }
 clean_exit:  clean_exit:
Line 3736  PHP_FUNCTION(openssl_private_encrypt) Line 3864  PHP_FUNCTION(openssl_private_encrypt)
         int data_len;          int data_len;
         long padding = RSA_PKCS1_PADDING;          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;                  return;
         }          }
         RETVAL_FALSE;          RETVAL_FALSE;
Line 3754  PHP_FUNCTION(openssl_private_encrypt) Line 3882  PHP_FUNCTION(openssl_private_encrypt)
         switch (pkey->type) {          switch (pkey->type) {
                 case EVP_PKEY_RSA:                  case EVP_PKEY_RSA:
                 case EVP_PKEY_RSA2:                  case EVP_PKEY_RSA2:
                        successful =  (RSA_private_encrypt(data_len,                         successful =  (RSA_private_encrypt(data_len,
                                                (unsigned char *)data,                                                 (unsigned char *)data,
                                                cryptedbuf,                                                 cryptedbuf,
                                                pkey->pkey.rsa,                                                 pkey->pkey.rsa,
                                                 padding) == cryptedlen);                                                  padding) == cryptedlen);
                         break;                          break;
                 default:                  default:
Line 3774  PHP_FUNCTION(openssl_private_encrypt) Line 3902  PHP_FUNCTION(openssl_private_encrypt)
         if (cryptedbuf) {          if (cryptedbuf) {
                 efree(cryptedbuf);                  efree(cryptedbuf);
         }          }
        if (keyresource == -1) {         if (keyresource == -1) {
                 EVP_PKEY_free(pkey);                  EVP_PKEY_free(pkey);
         }          }
 }  }
Line 3812  PHP_FUNCTION(openssl_private_decrypt) Line 3940  PHP_FUNCTION(openssl_private_decrypt)
         switch (pkey->type) {          switch (pkey->type) {
                 case EVP_PKEY_RSA:                  case EVP_PKEY_RSA:
                 case EVP_PKEY_RSA2:                  case EVP_PKEY_RSA2:
                        cryptedlen = RSA_private_decrypt(data_len,                         cryptedlen = RSA_private_decrypt(data_len,
                                        (unsigned char *)data,                                         (unsigned char *)data,
                                        crypttemp,                                         crypttemp,
                                        pkey->pkey.rsa,                                         pkey->pkey.rsa,
                                         padding);                                          padding);
                         if (cryptedlen != -1) {                          if (cryptedlen != -1) {
                                 cryptedbuf = emalloc(cryptedlen + 1);                                  cryptedbuf = emalloc(cryptedlen + 1);
Line 3840  PHP_FUNCTION(openssl_private_decrypt) Line 3968  PHP_FUNCTION(openssl_private_decrypt)
         if (keyresource == -1) {          if (keyresource == -1) {
                 EVP_PKEY_free(pkey);                  EVP_PKEY_free(pkey);
         }          }
        if (cryptedbuf) {         if (cryptedbuf) {
                 efree(cryptedbuf);                  efree(cryptedbuf);
         }          }
 }  }
Line 3864  PHP_FUNCTION(openssl_public_encrypt) Line 3992  PHP_FUNCTION(openssl_public_encrypt)
                 return;                  return;
   
         RETVAL_FALSE;          RETVAL_FALSE;
        
         pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);          pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
         if (pkey == NULL) {          if (pkey == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
Line 3877  PHP_FUNCTION(openssl_public_encrypt) Line 4005  PHP_FUNCTION(openssl_public_encrypt)
         switch (pkey->type) {          switch (pkey->type) {
                 case EVP_PKEY_RSA:                  case EVP_PKEY_RSA:
                 case EVP_PKEY_RSA2:                  case EVP_PKEY_RSA2:
                        successful = (RSA_public_encrypt(data_len,                         successful = (RSA_public_encrypt(data_len,
                                                (unsigned char *)data,                                                 (unsigned char *)data,
                                                cryptedbuf,                                                 cryptedbuf,
                                                pkey->pkey.rsa,                                                 pkey->pkey.rsa,
                                                 padding) == cryptedlen);                                                  padding) == cryptedlen);
                         break;                          break;
                 default:                  default:
Line 3923  PHP_FUNCTION(openssl_public_decrypt) Line 4051  PHP_FUNCTION(openssl_public_decrypt)
                 return;                  return;
         }          }
         RETVAL_FALSE;          RETVAL_FALSE;
        
         pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);          pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
         if (pkey == NULL) {          if (pkey == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
Line 3936  PHP_FUNCTION(openssl_public_decrypt) Line 4064  PHP_FUNCTION(openssl_public_decrypt)
         switch (pkey->type) {          switch (pkey->type) {
                 case EVP_PKEY_RSA:                  case EVP_PKEY_RSA:
                 case EVP_PKEY_RSA2:                  case EVP_PKEY_RSA2:
                        cryptedlen = RSA_public_decrypt(data_len,                         cryptedlen = RSA_public_decrypt(data_len,
                                        (unsigned char *)data,                                         (unsigned char *)data,
                                        crypttemp,                                         crypttemp,
                                        pkey->pkey.rsa,                                         pkey->pkey.rsa,
                                         padding);                                          padding);
                         if (cryptedlen != -1) {                          if (cryptedlen != -1) {
                                 cryptedbuf = emalloc(cryptedlen + 1);                                  cryptedbuf = emalloc(cryptedlen + 1);
Line 3947  PHP_FUNCTION(openssl_public_decrypt) Line 4075  PHP_FUNCTION(openssl_public_decrypt)
                                 successful = 1;                                  successful = 1;
                         }                          }
                         break;                          break;
                        
                 default:                  default:
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
                 
         }          }
   
         efree(crypttemp);          efree(crypttemp);
Line 4068  PHP_FUNCTION(openssl_verify) Line 4196  PHP_FUNCTION(openssl_verify)
         char * signature;       int signature_len;          char * signature;       int signature_len;
         zval *method = NULL;          zval *method = NULL;
         long signature_algo = OPENSSL_ALGO_SHA1;          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) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
                 return;                  return;
         }          }
Line 4127  PHP_FUNCTION(openssl_seal) Line 4255  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) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
                 return;                  return;
         }          }
        
         pubkeysht = HASH_OF(pubkeys);          pubkeysht = HASH_OF(pubkeys);
         nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;          nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
         if (!nkeys) {          if (!nkeys) {
Line 4222  clean_exit: Line 4350  clean_exit:
                 if (key_resources[i] == -1) {                  if (key_resources[i] == -1) {
                         EVP_PKEY_free(pkeys[i]);                          EVP_PKEY_free(pkeys[i]);
                 }                  }
                if (eks[i]) {                 if (eks[i]) {
                         efree(eks[i]);                          efree(eks[i]);
                 }                  }
         }          }
Line 4268  PHP_FUNCTION(openssl_open) Line 4396  PHP_FUNCTION(openssl_open)
         } else {          } else {
                 cipher = EVP_rc4();                  cipher = EVP_rc4();
         }          }
        
         buf = emalloc(data_len + 1);          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_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)) {                  if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
                         efree(buf);                          efree(buf);
                        if (keyresource == -1) {                         if (keyresource == -1) {
                                 EVP_PKEY_free(pkey);                                  EVP_PKEY_free(pkey);
                         }                          }
                         RETURN_FALSE;                          RETURN_FALSE;
Line 4511  SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream Line 4639  SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream
                                 if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {                                  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);                                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
                                         return NULL;                                          return NULL;
                                }                                               }
                         }                          }
   
                         tmpssl = SSL_new(ctx);                          tmpssl = SSL_new(ctx);
Line 4568  PHP_FUNCTION(openssl_get_md_methods) Line 4696  PHP_FUNCTION(openssl_get_md_methods)
         }          }
         array_init(return_value);          array_init(return_value);
         OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,          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);                  return_value);
 }  }
 /* }}} */  /* }}} */
Line 4584  PHP_FUNCTION(openssl_get_cipher_methods) Line 4712  PHP_FUNCTION(openssl_get_cipher_methods)
         }          }
         array_init(return_value);          array_init(return_value);
         OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,          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);                  return_value);
 }  }
 /* }}} */  /* }}} */
Line 4668  static zend_bool php_openssl_validate_iv(char **piv, i Line 4796  static zend_bool php_openssl_validate_iv(char **piv, i
   
 }  }
   
/* {{{ proto string openssl_encrypt(string data, string method, string password [, bool raw_output=false [, string $iv='']])/* {{{ proto string openssl_encrypt(string data, string method, string password [, long options=0 [, string $iv='']])
    Encrypts given data with given method and key, returns raw or base64 encoded string */     Encrypts given data with given method and key, returns raw or base64 encoded string */
 PHP_FUNCTION(openssl_encrypt)  PHP_FUNCTION(openssl_encrypt)
 {  {
        zend_bool raw_output = 0;        long options = 0;
         char *data, *method, *password, *iv = "";          char *data, *method, *password, *iv = "";
         int data_len, method_len, password_len, iv_len = 0, max_iv_len;          int data_len, method_len, password_len, iv_len = 0, max_iv_len;
         const EVP_CIPHER *cipher_type;          const EVP_CIPHER *cipher_type;
         EVP_CIPHER_CTX cipher_ctx;          EVP_CIPHER_CTX cipher_ctx;
        int i, outlen, keylen;        int i=0, outlen, keylen;
         unsigned char *outbuf, *key;          unsigned char *outbuf, *key;
         zend_bool free_iv;          zend_bool free_iv;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|bs", &data, &data_len, &method, &method_len, &password, &password_len, &raw_output, &iv, &iv_len) == FAILURE) {        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
                 return;                  return;
         }          }
         cipher_type = EVP_get_cipherbyname(method);          cipher_type = EVP_get_cipherbyname(method);
Line 4713  PHP_FUNCTION(openssl_encrypt) Line 4841  PHP_FUNCTION(openssl_encrypt)
                 EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);                  EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
         }          }
         EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);          EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
           if (options & OPENSSL_ZERO_PADDING) {
                   EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
           }
         if (data_len > 0) {          if (data_len > 0) {
                 EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);                  EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
         }          }
         outlen = i;          outlen = i;
         if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {          if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
                 outlen += i;                  outlen += i;
                if (raw_output) {                if (options & OPENSSL_RAW_DATA) {
                         outbuf[outlen] = '\0';                          outbuf[outlen] = '\0';
                         RETVAL_STRINGL((char *)outbuf, outlen, 0);                          RETVAL_STRINGL((char *)outbuf, outlen, 0);
                 } else {                  } else {
Line 4744  PHP_FUNCTION(openssl_encrypt) Line 4875  PHP_FUNCTION(openssl_encrypt)
 }  }
 /* }}} */  /* }}} */
   
/* {{{ proto string openssl_decrypt(string data, string method, string password [, bool raw_input=false [, string $iv = '']])/* {{{ proto string openssl_decrypt(string data, string method, string password [, long options=0 [, string $iv = '']])
    Takes raw or base64 encoded string and dectupt it using given method and key */     Takes raw or base64 encoded string and dectupt it using given method and key */
 PHP_FUNCTION(openssl_decrypt)  PHP_FUNCTION(openssl_decrypt)
 {  {
        zend_bool raw_input = 0;        long options = 0;
         char *data, *method, *password, *iv = "";          char *data, *method, *password, *iv = "";
         int data_len, method_len, password_len, iv_len = 0;          int data_len, method_len, password_len, iv_len = 0;
         const EVP_CIPHER *cipher_type;          const EVP_CIPHER *cipher_type;
Line 4759  PHP_FUNCTION(openssl_decrypt) Line 4890  PHP_FUNCTION(openssl_decrypt)
         char *base64_str = NULL;          char *base64_str = NULL;
         zend_bool free_iv;          zend_bool free_iv;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|bs", &data, &data_len, &method, &method_len, &password, &password_len, &raw_input, &iv, &iv_len) == FAILURE) {        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
                 return;                  return;
         }          }
   
Line 4774  PHP_FUNCTION(openssl_decrypt) Line 4905  PHP_FUNCTION(openssl_decrypt)
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
   
        if (!raw_input) {        if (!(options & OPENSSL_RAW_DATA)) {
                 base64_str = (char*)php_base64_decode((unsigned char*)data, data_len, &base64_str_len);                  base64_str = (char*)php_base64_decode((unsigned char*)data, data_len, &base64_str_len);
                   if (!base64_str) {
                           php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to base64 decode the input");
                           RETURN_FALSE;
                   }
                 data_len = base64_str_len;                  data_len = base64_str_len;
                 data = base64_str;                  data = base64_str;
         }          }
Line 4799  PHP_FUNCTION(openssl_decrypt) Line 4934  PHP_FUNCTION(openssl_decrypt)
                 EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);                  EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
         }          }
         EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);          EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
           if (options & OPENSSL_ZERO_PADDING) {
                   EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
           }
         EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);          EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
         outlen = i;          outlen = i;
         if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {          if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
Line 4910  PHP_FUNCTION(openssl_random_pseudo_bytes) Line 5048  PHP_FUNCTION(openssl_random_pseudo_bytes)
   
         buffer = emalloc(buffer_length + 1);          buffer = emalloc(buffer_length + 1);
   
   #ifdef PHP_WIN32
           strong_result = 1;
           /* random/urandom equivalent on Windows */
           if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE) {
                   efree(buffer);
                   if (zstrong_result_returned) {
                           ZVAL_BOOL(zstrong_result_returned, 0);
                   }
                   RETURN_FALSE;
           }
   #else
         if ((strong_result = RAND_pseudo_bytes(buffer, buffer_length)) < 0) {          if ((strong_result = RAND_pseudo_bytes(buffer, buffer_length)) < 0) {
                 efree(buffer);                  efree(buffer);
                   if (zstrong_result_returned) {
                           ZVAL_BOOL(zstrong_result_returned, 0);
                   }
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
   #endif
   
         buffer[buffer_length] = 0;          buffer[buffer_length] = 0;
         RETVAL_STRINGL((char *)buffer, buffer_length, 0);          RETVAL_STRINGL((char *)buffer, buffer_length, 0);

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>