php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #38917
Patch spki.patch revision 2011-12-22 10:41 UTC by jason dot gerfen at gmail dot com
revision 2011-12-21 20:31 UTC by jason dot gerfen at gmail dot com
revision 2011-12-21 16:09 UTC by jason dot gerfen at gmail dot com
revision 2011-12-21 03:48 UTC by jason dot gerfen at gmail dot com
revision 2011-12-21 03:26 UTC by jason dot gerfen at gmail dot com
revision 2011-12-19 17:58 UTC by jason dot gerfen at gmail dot com
revision 2011-12-19 17:53 UTC by jason dot gerfen at gmail dot com
revision 2011-12-19 14:36 UTC by jason dot gerfen at gmail dot com
revision 2011-12-14 11:38 UTC by jason dot gerfen at gmail dot com
revision 2011-12-13 16:55 UTC by jason dot gerfen at gmail dot com
revision 2011-12-08 10:57 UTC by jason dot gerfen at gmail dot com
revision 2011-12-06 21:02 UTC by jason dot gerfen at gmail dot com
revision 2011-12-06 11:35 UTC by jason dot gerfen at gmail dot com
revision 2011-12-06 11:29 UTC by jason dot gerfen at gmail dot com

Patch spki.patch for OpenSSL related Bug #38917

Patch version 2011-12-22 10:41 UTC

Return to Bug #38917 | Download this patch
Patch Revisions: 2011-12-22 10:41 UTC | 2011-12-21 20:31 UTC | 2011-12-21 16:09 UTC | 2011-12-21 03:48 UTC | 2011-12-21 03:26 UTC | 2011-12-19 17:58 UTC | 2011-12-19 17:53 UTC | 2011-12-19 14:36 UTC | 2011-12-14 11:38 UTC | 2011-12-13 16:55 UTC | 2011-12-08 10:57 UTC | 2011-12-06 21:02 UTC | 2011-12-06 11:35 UTC | 2011-12-06 11:29 UTC

Developer: jason.gerfen@gmail.com

Line 1 (now 1), was 181 lines, now 129 lines
 diff -Naur php-5.3.8/ext/openssl/openssl.c php-5.3.8-patched/ext/openssl/openssl.c
 --- php-5.3.8/ext/openssl/openssl.c	2011-07-25 05:42:53.000000000 -0600
 +++ php-5.3.8-patched/ext/openssl/openssl.c	2011-12-06 04:24:32.403578621 -0700
 @@ -16,7 +16,7 @@
     |          Wez Furlong <wez@thebrainroom.com>                          |
     |          Sascha Kettler <kettler@gmx.net>                            |
     |          Pierre-Alain Joye <pierre@php.net>                          |
 -   |          Marc Delling <delling@silpion.de> (PKCS12 functions)        |		
 +   |          Marc Delling <delling@silpion.de> (PKCS12 functions)        |
     +----------------------------------------------------------------------+
   */
  
 @@ -372,11 +372,30 @@
 --- php-5.3.8/ext/openssl/openssl.c 2011-07-25 05:42:53.000000000 -0600
 +++ php-5.3.8/ext/openssl/openssl.c 2011-12-21 09:15:38.000000000 -0700
 @@ -372,11 +372,40 @@
       ZEND_ARG_INFO(0, length)
       ZEND_ARG_INFO(1, result_is_strong)
   ZEND_END_ARG_INFO()
  +
 +ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_spki_new, 0, 0, 0)
 +ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_spki_new, 0, 0, 2)
  +    ZEND_ARG_INFO(0, privkey)
 +    ZEND_ARG_INFO(0, password)
 +    ZEND_ARG_INFO(0, spki_hash)
 +    ZEND_ARG_INFO(0, challenge)
 +    ZEND_ARG_INFO(0, algo)
  +ZEND_END_ARG_INFO()
  +
  +ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_verify, 0)
  +    ZEND_ARG_INFO(0, spki)
  +ZEND_END_ARG_INFO()
  +
  +ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_export, 0)
 +    ZEND_ARG_INFO(0, spki)
 +ZEND_END_ARG_INFO()
 +
 +ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_export_challenge, 0)
 +    ZEND_ARG_INFO(0, spki)
 +ZEND_END_ARG_INFO()
 +
 +ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_details, 0)
  +    ZEND_ARG_INFO(0, spki)
  +ZEND_END_ARG_INFO()
   /* }}} */
   
   /* {{{ openssl_functions[]
    */
   const zend_function_entry openssl_functions[] = {
  +/* spki functions */
 +	PHP_FE(openssl_spki_new, 		arginfo_openssl_spki_new)
 +	PHP_FE(openssl_spki_verify,		arginfo_openssl_spki_verify)
 +	PHP_FE(openssl_spki_export,		arginfo_openssl_spki_export)
 +	PHP_FE(openssl_spki_new, arginfo_openssl_spki_new)
 +	PHP_FE(openssl_spki_verify, arginfo_openssl_spki_verify)
 +	PHP_FE(openssl_spki_export, arginfo_openssl_spki_export)
 + PHP_FE(openssl_spki_export_challenge, arginfo_openssl_spki_export_challenge)
 + PHP_FE(openssl_spki_details,	arginfo_openssl_spki_details)
  +
   /* public/private key functions */
   	PHP_FE(openssl_pkey_free,			arginfo_openssl_pkey_free)
   	PHP_FE(openssl_pkey_new,			arginfo_openssl_pkey_new)
 @@ -506,7 +525,7 @@
  	if (php_check_open_basedir(filename TSRMLS_CC)) {
  		return -1;
  	}
 -	
 +
  	return 0;
  }
  /* }}} */
 @@ -563,7 +582,7 @@
  	} else {
  		subitem = val;
  	}
 -	
 +
  	for (i = 0; i < X509_NAME_entry_count(name); i++) {
  		unsigned char *to_add;
  		int to_add_len;
 @@ -606,7 +625,7 @@
  			last = j;
  		}
  		i = last;
 -		
 +
  		if (obj_cnt > 1) {
  			add_assoc_zval_ex(subitem, sname, strlen(sname) + 1, subentries);
  		} else {
 @@ -706,7 +725,7 @@
  #endif
  {
  	X509V3_CTX ctx;
 -	
 +
  	X509V3_set_ctx_test(&ctx);
  	X509V3_set_conf_lhash(&ctx, config);
  	if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) {
 @@ -816,7 +835,7 @@
  			req->priv_key_encrypt = 1;
  		}
  	}
 -	
 +
  	/* digest alg */
  	if (req->digest_name == NULL) {
  		req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
 @@ -838,7 +857,7 @@
  	}
  
  	PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);
 -	
 +
  	return SUCCESS;
  }
  /* }}} */
 @@ -991,10 +1010,10 @@
  	/* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
  	 * OpenSSL callbacks */
  	ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL);
 -	
 +
  	REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_CS|CONST_PERSISTENT);
  	REGISTER_LONG_CONSTANT("OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER, CONST_CS|CONST_PERSISTENT);
 -	
 +
  	/* purposes for cert purpose checking */
  	REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT);
  	REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT);
 @@ -1084,7 +1103,7 @@
  
  	php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
  	php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
 -	
 +
  	return SUCCESS;
  }
  /* }}} */
 @@ -1252,6 +1271,151 @@
 @@ -1252,6 +1281,291 @@
   }
   /* }}} */
   
 +/* {{{ proto string openssl_spki_new(mixed priv_key, string password)
 +/* {{{ proto string openssl_spki_new(mixed zpkey, string challenge [, string algo='sha256'])
  +   Creates new private key (or uses existing) and creates a new spki cert
  +   outputting results to var */
  +PHP_FUNCTION(openssl_spki_new)
  +{
 + zval * zout, * zpkey = NULL;
 + zval * zpkey = NULL;
  + EVP_PKEY * pkey = NULL;
  + NETSCAPE_SPKI *spki=NULL;
 + char * password, * spkstr;
 + long keyresource;
 + int challenge_len, algo_len;
 + char * challenge, * spkstr, *algo="sha256";
 + long keyresource = -1;
  + const char *spkac = "SPKAC=";
  +
 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &zpkey, &challenge, &challenge_len, &algo, &algo_len) == FAILURE) {
 +  return;
 + }
  + RETVAL_FALSE;
  +
 + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &zpkey, &password, &zout);
 +
 + pkey = php_openssl_evp_from_zval(&zpkey, 0, password, 1, &keyresource TSRMLS_CC);
 + pkey = php_openssl_evp_from_zval(&zpkey, 0, challenge, 1, &keyresource TSRMLS_CC);
  +
  + if (pkey == NULL) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 1");
  +  goto cleanup;
  + }
  +
  + if ((spki = NETSCAPE_SPKI_new()) == NULL) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get spki interface");
  +  goto cleanup;
  + }
  +
 + if (password) {
 +  ASN1_STRING_set(spki->spkac->challenge, password, (int)strlen(password));
 + if (challenge) {
 +  ASN1_STRING_set(spki->spkac->challenge, challenge, (int)strlen(challenge));
  + }
  +
  + if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get public key from spki");
  +  goto cleanup;
  + }
  +
 + if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_md5())) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot sign public key with spki");
 +  goto cleanup;
 + if (strcmp(algo, "md5")==0){
 +  if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_md5())) {
 +   goto cleanup;
 +  }
 + } else if(strcmp(algo, "sha1")==0){
 +  if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_sha1())) {
 +   goto cleanup;
 +  }
 + } else if(strcmp(algo, "sha256")==0){
 +  if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_sha256())) {
 +   goto cleanup;
 +  }
 + } else if (strcmp(algo, "sha512")==0){
 +  if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_sha512())) {
 +   goto cleanup;
 +  }
  + }
  +
  + spkstr = NETSCAPE_SPKI_b64_encode(spki);
 + if (!spkstr){
 +  goto cleanup;
 + }
  +
 + char * s = malloc(snprintf(NULL, 0, "%s%s", spkac, spkstr) + 1);
 + char * s = malloc(snprintf(NULL, 0, "%s%s", spkac, spkstr));
  + sprintf(s, "%s%s", spkac, spkstr);
  +
 + RETVAL_STRINGL(s, strlen(s), 0);
 + if (strlen(s)<=0) {
 +  goto cleanup;
 + }
 + RETURN_STRING(s, 1);
  +
  +cleanup:
 + if (keyresource == -1 && pkey) {
 + if (keyresource == -1 && spki) {
  +  NETSCAPE_SPKI_free(spki);
 + }
 + if (keyresource == -1 && pkey) {
  +  EVP_PKEY_free(pkey);
  + }
 + if (keyresource == -1 && s) {
 +  free(s);
 + }
 + RETURN_NULL();
  +}
  +/* }}} */
  +
  +/* {{{ proto bool openssl_spki_verify(string spki)


  + EVP_PKEY *pkey = NULL;
  + NETSCAPE_SPKI *spki = NULL;
  +
  + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "missing argument 1");
 +  goto cleanup;
 +  return;
  + }
  +
  + if (!spkstr) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "spki not found");
  +  goto cleanup;
  + }
  +
 + spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
 + char * spkstr_cleaned = malloc(strlen(spkstr));
 + openssl_spki_cleanup(spkstr, spkstr_cleaned);
 +
 + spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
  + if (!spki) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "error decoding spki");
  +  goto cleanup;
  + }
  +
 + pkey = NETSCAPE_SPKI_get_pubkey(spki);
 + pkey = X509_PUBKEY_get(spki->spkac->pubkey);
  + if (pkey == NULL) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "error getting public key from spki");
  +  goto cleanup;
  + }
  +
  + i = NETSCAPE_SPKI_verify(spki, pkey);
  +
  + if (i > 0) {
  +  x = 1;
 + } else {
 +  x = 0;
  + }
  + goto cleanup;
  +
  +cleanup:
 + EVP_PKEY_free(pkey);
 + RETVAL_BOOL(x);
 + if (spki) {
 +  NETSCAPE_SPKI_free(spki);
 + }
 + if (pkey) {
 +  EVP_PKEY_free(pkey);
 + }
 + RETURN_BOOL(x);
  +}
  +/* }}} */
  +
  +/* {{{ proto string openssl_spki_export(string spki)
Line 230 (now 180), was 872 lines, now 382 lines

  +{
  + int spkstr_len;
  + EVP_PKEY *pkey = NULL;
  + NETSCAPE_SPKI *spki = NULL;
 + BIO *out = BIO_new_fp(stdout, BIO_NOCLOSE);
 + BIO *out = BIO_new(BIO_s_mem());
 + BUF_MEM *bio_buf;
  + char *spkstr;
 +
 + RETVAL_FALSE;
  +
  + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "missing argument 1");
  +  goto cleanup;
  + }
  +
  + if (!spkstr) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "spki not found");
  +  goto cleanup;
  + }
  +
 + spki = NETSCAPE_SPKI_b64_decode(spkstr, strlen(spkstr));
 + char * spkstr_cleaned = malloc(strlen(spkstr));
 + openssl_spki_cleanup(spkstr, spkstr_cleaned);
 +
 + spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
  + if (!spki) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "error decoding spki");
  +  goto cleanup;
  + }
  +
 + pkey = NETSCAPE_SPKI_get_pubkey(spki);
 + pkey = X509_PUBKEY_get(spki->spkac->pubkey);
  + if (!pkey) {
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "error getting public key from spki");
  +  goto cleanup;
  + }
  +
  + PEM_write_bio_PUBKEY(out, pkey);
 + BIO_get_mem_ptr(out, &bio_buf);
 +
 + if ((!bio_buf->data)&&(bio_buf->length<=0)) {
 +  goto cleanup;
 + }
 +
 + char * s = malloc(bio_buf->length);
 + BIO_read(out, s, bio_buf->length);
 + RETURN_STRING(s, 1);
  +
  +cleanup:
 + NETSCAPE_SPKI_free(spki);
 + EVP_PKEY_free(pkey);
 + if (spki) {
 +  NETSCAPE_SPKI_free(spki);
 + }
 + if (out) {
 +  BIO_free_all(out);
 + }
 + if (pkey) {
 +  EVP_PKEY_free(pkey);
 + }
  +}
  +/* }}} */
  +
  /* {{{ proto bool openssl_x509_export(mixed x509, string &out [, bool notext = true])
     Exports a CERT to file or a var */
  PHP_FUNCTION(openssl_x509_export)
 @@ -1304,14 +1468,14 @@
  	long certresource = -1, keyresource = -1;
  
  	RETVAL_FALSE;
 -	
 +/* {{{ proto string openssl_spki_export_challenge(string spki)
 +   Exports spkac challenge from existing spki to var */
 +PHP_FUNCTION(openssl_spki_export_challenge)
 +{
 + int spkstr_len;
 + NETSCAPE_SPKI *spki = NULL;
 + char *spkstr;
  +
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) {
  		return;
  	}
  	cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
  	if (cert == NULL) {
  		RETURN_FALSE;
 -	}	
 +	}
  	key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC);
  	if (key) {
  		RETVAL_BOOL(X509_check_private_key(cert, key));
 @@ -1364,11 +1528,11 @@
  		snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));
  		add_assoc_string(return_value, "hash", buf, 1);
  	}
 -	
 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
 +  goto cleanup;
 + }
  +
  	add_assoc_name_entry(return_value, "issuer", 		X509_get_issuer_name(cert), useshortnames TSRMLS_CC);
  	add_assoc_long(return_value, "version", 			X509_get_version(cert));
  
 -	add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1); 
 +	add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1);
  
  	add_assoc_asn1_string(return_value, "validFrom", 	X509_get_notBefore(cert));
  	add_assoc_asn1_string(return_value, "validTo", 		X509_get_notAfter(cert));
 @@ -1570,8 +1734,8 @@
  	if (certresource == 1 && cert) {
  		X509_free(cert);
  	}
 -	if (cainfo) { 
 -		X509_STORE_free(cainfo); 
 +	if (cainfo) {
 +		X509_STORE_free(cainfo);
  	}
  	if (untrustedchain) {
  		sk_X509_pop_free(untrustedchain, X509_free);
 @@ -1624,7 +1788,7 @@
  				dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
  				if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_PP(item), X509_FILETYPE_PEM)) {
  					php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_PP(item));
 -				} else { 
 +				} else {
  					ndirs++;
  				}
  				dir_lookup = NULL;
 @@ -1718,11 +1882,11 @@
  
  			if (certresource != -1) {
  				cert = X509_dup(cert);
 -				
 + if (!spkstr) {
 +  goto cleanup;
 + }
  +
  				if (cert == NULL) {
  					goto clean_exit;
  				}
 -				
 + char * spkstr_cleaned = malloc(strlen(spkstr));
 + openssl_spki_cleanup(spkstr, spkstr_cleaned);
  +
  			}
  			sk_X509_push(sk, cert);
  
 @@ -1731,7 +1895,7 @@
  	} else {
  		/* a single certificate */
  		cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC);
 -		
 + spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
 + if (!spki) {
 +  goto cleanup;
 + }
  +
  		if (cert == NULL) {
  			goto clean_exit;
  		}
 @@ -1776,7 +1940,7 @@
  	if (strlen(filename) != filename_len) {
  		return;
  	}
 -	
 + RETURN_STRING(ASN1_STRING_data(spki->spkac->challenge), 1);
  +
  	cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
  	if (cert == NULL) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
 @@ -1812,9 +1976,9 @@
  
  	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) {
 -		
 +cleanup:
 + if (spki) {
 +  NETSCAPE_SPKI_free(spki);
 + }
 +}
 +/* }}} */
  +
  		i2d_PKCS12_bio(bio_out, p12);
  
  		RETVAL_TRUE;
 @@ -1825,13 +1989,13 @@
  	BIO_free(bio_out);
  	PKCS12_free(p12);
  	php_sk_X509_free(ca);
 -	
 +/* {{{ proto string openssl_spki_details(string spki)
 +   Provides details from existing spki to var */
 +PHP_FUNCTION(openssl_spki_details)
 +{
 + int spkstr_len;
 + NETSCAPE_SPKI *spki = NULL;
 + BIO *out = BIO_new(BIO_s_mem());
 + BUF_MEM *bio_buf;
 + zval *zout;
 + char *spkstr;
  +
  cleanup:
  
  	if (keyresource == -1 && priv_key) {
  		EVP_PKEY_free(priv_key);
  	}
 -	if (certresource == -1 && cert) { 
 +	if (certresource == -1 && cert) {
  		X509_free(cert);
  	}
  }
 @@ -1857,7 +2021,7 @@
  		return;
  
  	RETVAL_FALSE;
 -	
 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
 +  return;
 + }
 + RETVAL_FALSE;
  +
  	cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
  	if (cert == NULL) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
 @@ -1880,7 +2044,7 @@
  	if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
  		ca = php_array_to_X509_sk(item TSRMLS_CC);
  	/* end parse extra config */
 -	
 + if (!spkstr) {
 +  goto cleanup;
 + }
  +
  	p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
  
  	bio_out = BIO_new(BIO_s_mem());
 @@ -1897,13 +2061,13 @@
  	BIO_free(bio_out);
  	PKCS12_free(p12);
  	php_sk_X509_free(ca);
 -	
 + char * spkstr_cleaned = malloc(strlen(spkstr));
 + openssl_spki_cleanup(spkstr, spkstr_cleaned);
  +
  cleanup:
  
  	if (keyresource == -1 && priv_key) {
  		EVP_PKEY_free(priv_key);
  	}
 -	if (certresource == -1 && cert) { 
 +	if (certresource == -1 && cert) {
  		X509_free(cert);
  	}
  }
 @@ -1927,12 +2091,12 @@
  		return;
  
  	RETVAL_FALSE;
 -	
 + spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
 + if (!spki) {
 +  goto cleanup;
 + }
  +
  	bio_in = BIO_new(BIO_s_mem());
 -	
 + NETSCAPE_SPKI_print(out, spki);
 + BIO_get_mem_ptr(out, &bio_buf);
  +
  	if(!BIO_write(bio_in, zp12, zp12_len))
  		goto cleanup;
 -	
 + if ((!bio_buf->data)&&(bio_buf->length<=0)) {
 +  goto cleanup;
 + }
  +
  	if(d2i_PKCS12_bio(bio_in, &p12)) {
  		if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
  			BIO * bio_out;
 @@ -1962,12 +2126,12 @@
  
  			MAKE_STD_ZVAL(zextracerts);
  			array_init(zextracerts);
 -			
 + char * s = malloc(bio_buf->length);
 + BIO_read(out, s, bio_buf->length);
 + RETURN_STRING(s, 1);
  +
  			for (i=0;;i++) {
  				zval * zextracert;
  				X509* aCA = sk_X509_pop(ca);
  				if (!aCA) break;
 -				
 +cleanup:
 + if (spki) {
 +  NETSCAPE_SPKI_free(spki);
 + }
 + BIO_free_all(out);
 +}
 +/* }}} */
  +
  				bio_out = BIO_new(BIO_s_mem());
  				if (PEM_write_bio_X509(bio_out, aCA)) {
  					BUF_MEM *bio_buf;
 @@ -1975,7 +2139,7 @@
  					MAKE_STD_ZVAL(zextracert);
  					ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1);
  					add_index_zval(zextracerts, i, zextracert);
 -					
 +/* {{{ proto int openssl_spki_cleanup(const char *src, char *results)
 +  This will help remove new line chars in the SPKAC sent from the
 +  browser */
 +int openssl_spki_cleanup(const char *src, char *dest)
 +{
 +    int removed=0;
  +
  				}
  				BIO_free(bio_out);
 +    while (*src) {
 +        if (*src!='\n'&&*src!='\r') {
 +            *dest++=*src;
 +        } else {
 +            ++removed;
 +        }
 +        ++src;
 +    }
 +    *dest=0;
 +    return removed;
 +}
 +/* }}} */
 +
  /* {{{ proto bool openssl_x509_export(mixed x509, string &out [, bool notext = true])
     Exports a CERT to file or a var */
  PHP_FUNCTION(openssl_x509_export)
 --- php-5.3.8/ext/openssl/php_openssl.h	2010-12-31 19:19:59.000000000 -0700
 +++ php-5.3.8/ext/openssl/php_openssl.h	2011-12-21 09:15:38.000000000 -0700
 @@ -74,6 +74,12 @@
  PHP_FUNCTION(openssl_csr_sign);
  PHP_FUNCTION(openssl_csr_get_subject);
  PHP_FUNCTION(openssl_csr_get_public_key);
 +
 +PHP_FUNCTION(openssl_spki_new);
 +PHP_FUNCTION(openssl_spki_verify);
 +PHP_FUNCTION(openssl_spki_export);
 +PHP_FUNCTION(openssl_spki_export_challenge);
 +PHP_FUNCTION(openssl_spki_details);
  #else
   
 @@ -1987,13 +2151,13 @@
  			} else {
  				zval_dtor(zextracerts);
  			}
 -			
  #define phpext_openssl_ptr NULL
 --- php-5.3.8/ext/openssl/tests/026.phpt 1969-12-31 17:00:00.000000000 -0700
 +++ php-5.3.8/ext/openssl/tests/026.phpt 2011-12-21 12:45:39.000000000 -0700
 @@ -0,0 +1,208 @@
 +--TEST--
 +openssl_spki_new(), openssl_spki_verify(), openssl_spki_export(), openssl_spki_export_challenge(), openssl_spki_details()
 +--SKIPIF--
 +<?php
 +if (!extension_loaded("openssl")) die("skip");
 +if (!@openssl_pkey_new()) die("skip cannot create private key");
 +?>
 +--FILE--
 +<?php
  +
  			RETVAL_TRUE;
 -			
 +echo "Creating private key\n";
 +$key = openssl_pkey_new();
 +if ($key === false)
 + die("failed to create private key\n");
  +
  			PKCS12_free(p12);
  		}
  	}
 -	
 +echo "Creating new SPKAC with defaults\n";
 +if (!function_exists("openssl_spki_new"))
 + die("openssl_spki_new() does not exist\n");
  +
    cleanup:
  	if (bio_in) {
  		BIO_free(bio_in);
 @@ -2001,7 +2165,7 @@
  	if (pkey) {
  		EVP_PKEY_free(pkey);
  	}
 -	if (cert) { 
 +	if (cert) {
  		X509_free(cert);
  	}
  }
 @@ -2020,7 +2184,7 @@
  		return FAILURE;
  	}
  	dn_sk = CONF_get_section(req->req_config, dn_sect);
 -	if (dn_sk == NULL) { 
 +	if (dn_sk == NULL) {
  		return FAILURE;
  	}
  	attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
 @@ -2040,15 +2204,15 @@
  		X509_NAME * subj;
  		HashPosition hpos;
  		zval ** item;
 -		
 +$spki = openssl_spki_new($key, "sample_challenge_string");
 +if ($spki === false)
 + die("could not create spkac\n");
  +
  		subj = X509_REQ_get_subject_name(csr);
  		/* apply values from the dn hash */
  		zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos);
  		while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) {
 -			char * strindex = NULL; 
 +			char * strindex = NULL;
  			uint strindexlen = 0;
  			ulong intindex;
 -			
 +echo "Verifying SPKAC using defaults\n";
 +if (!function_exists("openssl_spki_verify"))
 + die("openssl_spki_verify() does not exist\n");
  +
  			zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos);
  
  			convert_to_string_ex(item);
 @@ -2058,7 +2222,7 @@
  
  				nid = OBJ_txt2nid(strindex);
  				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_ASC,
  								(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));
 @@ -2075,10 +2239,10 @@
  		for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
  			int len;
  			char buffer[200 + 1]; /*200 + \0 !*/
 -			
 +$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
 +if ($a === false)
 + die("could not verify spkac\n");
  +
  			v = sk_CONF_VALUE_value(dn_sk, i);
  			type = v->name;
 -			
 +echo "Exporting challenge using defaults\n";
 +if (!function_exists("openssl_spki_export_challenge"))
 + die("openssl_spki_export_challenge() does not exist\n");
  +
  			len = strlen(type);
  			if (len < sizeof("_default")) {
  				continue;
 @@ -2093,7 +2257,7 @@
  			memcpy(buffer, type, len);
  			buffer[len] = '\0';
  			type = buffer;
 -		
 +$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
 +if ($b !== "sample_challenge_string")
 + die("could not verify challenge string from spkac\n");
  +
  			/* Skip past any leading X. X: X, etc to allow for multiple
  			 * instances */
  			for (str = type; *str; str++) {
 @@ -2170,7 +2334,7 @@
  	X509_REQ * csr = NULL;
  	char * filename = NULL;
  	BIO * in;
 -	
 +echo "Exporting public key from SPKAC using defaults\n";
 +if (!function_exists("openssl_spki_export"))
 + die("openssl_spki_export() does not exist\n");
  +
  	if (resourceval) {
  		*resourceval = -1;
  	}
 @@ -2315,13 +2479,13 @@
  	long csr_resource, certresource = 0, keyresource = -1;
  	int i;
  	struct php_x509_request req;
 -	
 +$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
 +if ($c === "")
 + die("could not export public key from spkac\n");
  +
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ!Zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
  		return;
  
  	RETVAL_FALSE;
  	PHP_SSL_REQ_INIT(&req);
 -	
 +echo "Generating details of SPKAC structure using defaults\n";
 +if (!function_exists("openssl_spki_details"))
 + die("openssl_spki_details() does not exist\n");
  +
  	csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
  	if (csr == NULL) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
 @@ -2343,7 +2507,7 @@
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");
  		goto cleanup;
  	}
 -	
 +$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
 +if ($d === "")
 + die("could not obtain details from spkac\n");
  +
  	if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) {
  		goto cleanup;
  	}
 @@ -2363,9 +2527,9 @@
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");
  		goto cleanup;
  	}
 -	
 +unset($spki, $a, $b, $c, $d);
  +
  	/* Now we can get on with it */
 -	
 +echo "Creating new SPKAC using md5 signature\n";
 +if (!function_exists("openssl_spki_new"))
 + die("openssl_spki_new() does not exist\n");
  +
  	new_cert = X509_new();
  	if (new_cert == NULL) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");
 @@ -2376,7 +2540,7 @@
  		goto cleanup;
  
  	ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
 -	
 +$spki = openssl_spki_new($key, "sample_challenge_string", "md5");
 +if ($spki === false)
 + die("could not create spkac\n");
  +
  	X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
  
  	if (cert == NULL) {
 @@ -2393,7 +2557,7 @@
  	}
  	if (req.extensions_section) {
  		X509V3_CTX ctx;
 -		
 +echo "Verifying SPKAC using md5 signature\n";
 +if (!function_exists("openssl_spki_verify"))
 + die("openssl_spki_verify() does not exist\n");
  +
  		X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);
  		X509V3_set_conf_lhash(&ctx, req.req_config);
  		if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) {
 @@ -2406,11 +2570,11 @@
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");
  		goto cleanup;
  	}
 -	
 +$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
 +if ($a === false)
 + die("could not verify spkac\n");
  +
  	/* Succeeded; lets return the cert */
  	RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509));
  	new_cert = NULL;
 -	
 +echo "Exporting challenge using md5 signature\n";
 +if (!function_exists("openssl_spki_export_challenge"))
 + die("openssl_spki_export_challenge() does not exist\n");
  +
  cleanup:
  
  	if (cert == new_cert) {
 @@ -2427,7 +2591,7 @@
  	if (csr_resource == -1 && csr) {
  		X509_REQ_free(csr);
  	}
 -	if (certresource == -1 && cert) { 
 +	if (certresource == -1 && cert) {
  		X509_free(cert);
  	}
  	if (new_cert) {
 @@ -2446,12 +2610,12 @@
  	X509_REQ * csr = NULL;
  	int we_made_the_key = 1;
  	long key_resource;
 -	
 +$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
 +if ($b !== "sample_challenge_string")
 + die("could not verify challenge string from spkac\n");
  +
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
  		return;
  	}
  	RETVAL_FALSE;
 -	
 +echo "Exporting public key from SPKAC using md5 signature\n";
 +if (!function_exists("openssl_spki_export"))
 + die("openssl_spki_export() does not exist\n");
  +
  	PHP_SSL_REQ_INIT(&req);
  
  	if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
 @@ -2483,10 +2647,10 @@
  						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);
  					} else {
  						RETVAL_TRUE;
 -						
 +$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
 +if ($c === "")
 + die("could not export public key from spkac\n");
  +
  						if (X509_REQ_sign(csr, req.priv_key, req.digest)) {
  							RETVAL_RESOURCE(zend_list_insert(csr, le_csr));
 -							csr = NULL;			
 +							csr = NULL;
  						} else {
  							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");
  						}
 @@ -2611,14 +2775,14 @@
  	}
  	if (Z_TYPE_PP(val) == IS_ARRAY) {
  		zval ** zphrase;
 -		
 +echo "Generating details of SPKAC structure using md5 signature\n";
 +if (!function_exists("openssl_spki_details"))
 + die("openssl_spki_details() does not exist\n");
  +
  		/* get passphrase */
  
  		if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) {
  			php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
  			return NULL;
  		}
 -		
 +$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
 +if ($d === "")
 + die("could not obtain details from spkac\n");
  +
  		if (Z_TYPE_PP(zphrase) == IS_STRING) {
  			passphrase = Z_STRVAL_PP(zphrase);
  		} else {
 @@ -2643,7 +2807,7 @@
  		if (!what) {
  			TMP_CLEAN;
  		}
 -		if (resourceval) { 
 +		if (resourceval) {
  			*resourceval = Z_LVAL_PP(val);
  		}
  		if (type == le_x509) {
 @@ -2677,8 +2841,8 @@
  		}
  	} else {
  		/* force it to be a string and check if it refers to a file */
 -		/* passing non string values leaks, object uses toString, it returns NULL 
 -		 * See bug38255.phpt 
 +		/* passing non string values leaks, object uses toString, it returns NULL
 +		 * See bug38255.phpt
  		 */
  		if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {
  			TMP_CLEAN;
 @@ -2752,7 +2916,7 @@
  	char * randfile = NULL;
  	int egdsocket, seeded;
  	EVP_PKEY * return_val = NULL;
 -	
 +unset($spki, $a, $b, $c, $d);
  +
  	if (req->priv_key_bits < MIN_KEY_LENGTH) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d",
  				MIN_KEY_LENGTH, req->priv_key_bits);
 @@ -2761,7 +2925,7 @@
  
  	randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
  	php_openssl_load_rand_file(randfile, &egdsocket, &seeded);
 -	
 +echo "Creating new SPKAC using sha1 signature\n";
 +if (!function_exists("openssl_spki_new"))
 + die("openssl_spki_new() does not exist\n");
  +
  	if ((req->priv_key = EVP_PKEY_new()) != NULL) {
  		switch(req->priv_key_type) {
  			case OPENSSL_KEYTYPE_RSA:
 @@ -2811,13 +2975,13 @@
  	}
  
  	php_openssl_write_rand_file(randfile, egdsocket, seeded);
 -	
 +$spki = openssl_spki_new($key, "sample_challenge_string", "sha1");
 +if ($spki === false)
 + die("could not create spkac\n");
  +
  	if (return_val == NULL) {
  		EVP_PKEY_free(req->priv_key);
  		req->priv_key = NULL;
  		return NULL;
  	}
 -	
 +echo "Verifying SPKAC using sha1 signature\n";
 +if (!function_exists("openssl_spki_verify"))
 + die("openssl_spki_verify() does not exist\n");
  +
  	return return_val;
  }
  /* }}} */
 @@ -2846,7 +3010,7 @@
  		case EVP_PKEY_DSA4:
  			assert(pkey->pkey.dsa != NULL);
  
 -			if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){ 
 +			if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
  				return 0;
  			}
  			break;
 @@ -2977,7 +3141,7 @@
  			}
  			RETURN_FALSE;
  		}
 -	} 
 +	}
  
  	PHP_SSL_REQ_INIT(&req);
  
 @@ -3006,7 +3170,7 @@
  	EVP_PKEY * key;
  	BIO * bio_out = NULL;
  	const EVP_CIPHER * cipher;
 -	
 +$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
 +if ($a === false)
 + die("could not verify spkac\n");
  +
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
  		return;
  	}
 @@ -3022,11 +3186,11 @@
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
  		RETURN_FALSE;
  	}
 -	
 +echo "Exporting challenge using sha1 signature\n";
 +if (!function_exists("openssl_spki_export_challenge"))
 + die("openssl_spki_export_challenge() does not exist\n");
  +
  	if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
  		RETURN_FALSE;
  	}
 -	
 +$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
 +if ($b !== "sample_challenge_string")
 + die("could not verify challenge string from spkac\n");
  +
  	PHP_SSL_REQ_INIT(&req);
  
  	if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
 @@ -3065,7 +3229,7 @@
  	EVP_PKEY * key;
  	BIO * bio_out = NULL;
  	const EVP_CIPHER * cipher;
 -	
 +echo "Exporting public key from SPKAC using sha1 signature\n";
 +if (!function_exists("openssl_spki_export"))
 + die("openssl_spki_export() does not exist\n");
  +
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
  		return;
  	}
 @@ -3077,7 +3241,7 @@
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
  		RETURN_FALSE;
  	}
 -	
 +$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
 +if ($c === "")
 + die("could not export public key from spkac\n");
  +
  	PHP_SSL_REQ_INIT(&req);
  
  	if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
 @@ -3193,7 +3357,7 @@
  	array_init(return_value);
  	add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey));
  	add_assoc_stringl(return_value, "key", pbio, pbio_len, 1);
 -	/*TODO: Use the real values once the openssl constants are used 
 +	/*TODO: Use the real values once the openssl constants are used
  	 * See the enum at the top of this file
  	 */
  	switch (EVP_PKEY_type(pkey->type)) {
 @@ -3217,7 +3381,7 @@
  				add_assoc_zval(return_value, "rsa", rsa);
  			}
  
 -			break;	
 +			break;
  		case EVP_PKEY_DSA:
  		case EVP_PKEY_DSA2:
  		case EVP_PKEY_DSA3:
 @@ -3238,7 +3402,7 @@
  			}
  			break;
  		case EVP_PKEY_DH:
 -			
 +echo "Generating details of SPKAC structure using sha1 signature\n";
 +if (!function_exists("openssl_spki_details"))
 + die("openssl_spki_details() does not exist\n");
  +
  			ktype = OPENSSL_KEYTYPE_DH;
  
  			if (pkey->pkey.dh != NULL) {
 @@ -3254,7 +3418,7 @@
  			}
  
  			break;
 -#ifdef EVP_PKEY_EC 
 +#ifdef EVP_PKEY_EC
  		case EVP_PKEY_EC:
  			ktype = OPENSSL_KEYTYPE_EC;
  			break;
 @@ -3288,7 +3452,7 @@
  	char * extracerts = NULL; int extracerts_len = 0;
  	char * signersfilename = NULL; int signersfilename_len = 0;
  	char * datafilename = NULL; int datafilename_len = 0;
 -	
 +$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
 +if ($d === "")
 + die("could not obtain details from spkac\n");
  +
  	RETVAL_LONG(-1);
  
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|sass", &filename, &filename_len,
 @@ -3296,7 +3460,7 @@
  				&extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {
  		return;
  	}
 -	
 +unset($spki, $a, $b, $c, $d);
  +
  	if (extracerts) {
  		others = load_all_certs_from_file(extracerts);
  		if (others == NULL) {
 @@ -3348,11 +3512,11 @@
  
  		if (signersfilename) {
  			BIO *certout;
 -		
 +echo "Creating new SPKAC using sha512 signature\n";
 +if (!function_exists("openssl_spki_new"))
 + die("openssl_spki_new() does not exist\n");
  +
  			if (php_openssl_safe_mode_chk(signersfilename TSRMLS_CC)) {
  				goto clean_exit;
  			}
 -		
 +$spki = openssl_spki_new($key, "sample_challenge_string", "sha512");
 +if ($spki === false)
 + die("could not create spkac\n");
  +
  			certout = BIO_new_file(signersfilename, "w");
  			if (certout) {
  				int i;
 @@ -3401,7 +3565,7 @@
  	char * strindex;
  	char * infilename = NULL;	int infilename_len;
  	char * outfilename = NULL;	int outfilename_len;
 -	
 +echo "Verifying SPKAC using sha512 signature\n";
 +if (!function_exists("openssl_spki_verify"))
 + die("openssl_spki_verify() does not exist\n");
  +
  	RETVAL_FALSE;
  
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZa!|ll", &infilename, &infilename_len,
 @@ -3426,7 +3590,7 @@
  	}
  
  	outfile = BIO_new_file(outfilename, "w");
 -	if (outfile == NULL) { 
 +	if (outfile == NULL) {
  		goto clean_exit;
  	}
  
 @@ -3565,7 +3729,7 @@
  
  	if (extracertsfilename) {
  		others = load_all_certs_from_file(extracertsfilename);
 -		if (others == NULL) { 
 +		if (others == NULL) {
  			goto clean_exit;
  		}
  	}
 @@ -3684,7 +3848,7 @@
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key");
  		goto clean_exit;
  	}
 -	
 +$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
 +if ($a === false)
 + die("could not verify spkac\n");
  +
  	if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {
  		goto clean_exit;
  	}
 @@ -3703,7 +3867,7 @@
  	if (p7 == NULL) {
  		goto clean_exit;
  	}
 -	if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) { 
 +	if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
  		RETVAL_TRUE;
  	}
  clean_exit:
 @@ -3736,7 +3900,7 @@
  	int data_len;
  	long padding = RSA_PKCS1_PADDING;
  
 -	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { 
 +	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
  		return;
  	}
  	RETVAL_FALSE;
 @@ -3754,10 +3918,10 @@
  	switch (pkey->type) {
  		case EVP_PKEY_RSA:
  		case EVP_PKEY_RSA2:
 -			successful =  (RSA_private_encrypt(data_len, 
 -						(unsigned char *)data, 
 -						cryptedbuf, 
 -						pkey->pkey.rsa, 
 +			successful =  (RSA_private_encrypt(data_len,
 +						(unsigned char *)data,
 +						cryptedbuf,
 +						pkey->pkey.rsa,
  						padding) == cryptedlen);
  			break;
  		default:
 @@ -3774,7 +3938,7 @@
  	if (cryptedbuf) {
  		efree(cryptedbuf);
  	}
 -	if (keyresource == -1) { 
 +	if (keyresource == -1) {
  		EVP_PKEY_free(pkey);
  	}
  }
 @@ -3812,10 +3976,10 @@
  	switch (pkey->type) {
  		case EVP_PKEY_RSA:
  		case EVP_PKEY_RSA2:
 -			cryptedlen = RSA_private_decrypt(data_len, 
 -					(unsigned char *)data, 
 -					crypttemp, 
 -					pkey->pkey.rsa, 
 +			cryptedlen = RSA_private_decrypt(data_len,
 +					(unsigned char *)data,
 +					crypttemp,
 +					pkey->pkey.rsa,
  					padding);
  			if (cryptedlen != -1) {
  				cryptedbuf = emalloc(cryptedlen + 1);
 @@ -3840,7 +4004,7 @@
  	if (keyresource == -1) {
  		EVP_PKEY_free(pkey);
  	}
 -	if (cryptedbuf) { 
 +	if (cryptedbuf) {
  		efree(cryptedbuf);
  	}
  }
 @@ -3864,7 +4028,7 @@
  		return;
  
  	RETVAL_FALSE;
 -	
 +echo "Exporting challenge using sha512 signature\n";
 +if (!function_exists("openssl_spki_export_challenge"))
 + die("openssl_spki_export_challenge() does not exist\n");
  +
  	pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
  	if (pkey == NULL) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
 @@ -3877,10 +4041,10 @@
  	switch (pkey->type) {
  		case EVP_PKEY_RSA:
  		case EVP_PKEY_RSA2:
 -			successful = (RSA_public_encrypt(data_len, 
 -						(unsigned char *)data, 
 -						cryptedbuf, 
 -						pkey->pkey.rsa, 
 +			successful = (RSA_public_encrypt(data_len,
 +						(unsigned char *)data,
 +						cryptedbuf,
 +						pkey->pkey.rsa,
  						padding) == cryptedlen);
  			break;
  		default:
 @@ -3923,7 +4087,7 @@
  		return;
  	}
  	RETVAL_FALSE;
 -	
 +$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
 +if ($b !== "sample_challenge_string")
 + die("could not verify challenge string from spkac\n");
  +
  	pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
  	if (pkey == NULL) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
 @@ -3936,10 +4100,10 @@
  	switch (pkey->type) {
  		case EVP_PKEY_RSA:
  		case EVP_PKEY_RSA2:
 -			cryptedlen = RSA_public_decrypt(data_len, 
 -					(unsigned char *)data, 
 -					crypttemp, 
 -					pkey->pkey.rsa, 
 +			cryptedlen = RSA_public_decrypt(data_len,
 +					(unsigned char *)data,
 +					crypttemp,
 +					pkey->pkey.rsa,
  					padding);
  			if (cryptedlen != -1) {
  				cryptedbuf = emalloc(cryptedlen + 1);
 @@ -3947,10 +4111,10 @@
  				successful = 1;
  			}
  			break;
 -			
 +echo "Exporting public key from SPKAC using sha512 signature\n";
 +if (!function_exists("openssl_spki_export"))
 + die("openssl_spki_export() does not exist\n");
  +
  		default:
  			php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
 -		 
 +$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
 +if ($c === "")
 + die("could not export public key from spkac\n");
  +
  	}
  
  	efree(crypttemp);
 @@ -4068,7 +4232,7 @@
  	char * signature;	int signature_len;
  	zval *method = NULL;
  	long signature_algo = OPENSSL_ALGO_SHA1;
 -	
 +echo "Generating details of SPKAC structure using sha512 signature\n";
 +if (!function_exists("openssl_spki_details"))
 + die("openssl_spki_details() does not exist\n");
  +
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
  		return;
  	}
 @@ -4127,7 +4291,7 @@
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
  		return;
  	}
 -	
 +$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
 +if ($d === "")
 + die("could not obtain details from spkac\n");
  +
  	pubkeysht = HASH_OF(pubkeys);
  	nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
  	if (!nkeys) {
 @@ -4222,7 +4386,7 @@
  		if (key_resources[i] == -1) {
  			EVP_PKEY_free(pkeys[i]);
  		}
 -		if (eks[i]) { 
 +		if (eks[i]) {
  			efree(eks[i]);
  		}
  	}
 @@ -4268,13 +4432,13 @@
  	} else {
  		cipher = EVP_rc4();
  	}
 -	
 +echo "OK!\n";
  +
  	buf = emalloc(data_len + 1);
  
  	if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
  		if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
  			efree(buf);
 -			if (keyresource == -1) { 
 +			if (keyresource == -1) {
  				EVP_PKEY_free(pkey);
  			}
  			RETURN_FALSE;
 @@ -4511,7 +4675,7 @@
  				if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
  					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
  					return NULL;
 -				}		
 +				}
  			}
  
  			tmpssl = SSL_new(ctx);
 @@ -4568,7 +4732,7 @@
  	}
  	array_init(return_value);
  	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
 -		aliases ? openssl_add_method_or_alias: openssl_add_method, 
 +		aliases ? openssl_add_method_or_alias: openssl_add_method,
  		return_value);
  }
  /* }}} */
 @@ -4584,7 +4748,7 @@
  	}
  	array_init(return_value);
  	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
 -		aliases ? openssl_add_method_or_alias: openssl_add_method, 
 +		aliases ? openssl_add_method_or_alias: openssl_add_method,
  		return_value);
  }
  /* }}} */
 diff -Naur php-5.3.8/ext/openssl/php_openssl.h php-5.3.8-patched/ext/openssl/php_openssl.h
 --- php-5.3.8/ext/openssl/php_openssl.h	2010-12-31 19:19:59.000000000 -0700
 +++ php-5.3.8-patched/ext/openssl/php_openssl.h	2011-12-06 04:24:56.581276358 -0700
 @@ -74,6 +74,10 @@
  PHP_FUNCTION(openssl_csr_sign);
  PHP_FUNCTION(openssl_csr_get_subject);
  PHP_FUNCTION(openssl_csr_get_public_key);
 +
 +PHP_FUNCTION(openssl_spki_new);
 +PHP_FUNCTION(openssl_spki_verify);
 +PHP_FUNCTION(openssl_spki_export);
  #else
  
  #define phpext_openssl_ptr NULL
 +openssl_free_key($key);
 +?>
 +--EXPECT--
 +Creating private key
 +Creating new SPKAC with defaults
 +Verifying SPKAC using defaults
 +Exporting challenge using defaults
 +Exporting public key from SPKAC using defaults
 +Generating details of SPKAC structure using defaults
 +Creating new SPKAC using md5 signature
 +Verifying SPKAC using md5 signature
 +Exporting challenge using md5 signature
 +Exporting public key from SPKAC using md5 signature
 +Generating details of SPKAC structure using md5 signature
 +Creating new SPKAC using sha1 signature
 +Verifying SPKAC using sha1 signature
 +Exporting challenge using sha1 signature
 +Exporting public key from SPKAC using sha1 signature
 +Generating details of SPKAC structure using sha1 signature
 +Creating new SPKAC using sha512 signature
 +Verifying SPKAC using sha512 signature
 +Exporting challenge using sha512 signature
 +Exporting public key from SPKAC using sha512 signature
 +Generating details of SPKAC structure using sha512 signature
 +OK!
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 14:01:50 2014 UTC