Patch spki.patch for OpenSSL related Bug #38917
Patch version 2011-12-08 10:57 UTC
Return to Bug #38917 |
Download this patch
Patch Revisions:
Developer: jason.gerfen@gmail.com
--- php-5.3.8/ext/openssl/openssl.c
+++ php-5.3.8/ext/openssl/openssl.c
@@ -372,11 +372,35 @@
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_ARG_INFO(0, privkey)
+ ZEND_ARG_INFO(0, password)
+ ZEND_ARG_INFO(0, spki_hash)
+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_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_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)
@@ -1252,6 +1276,190 @@
}
/* }}} */
+/* {{{ proto string openssl_spki_new(mixed priv_key, string password)
+ 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;
+ EVP_PKEY * pkey = NULL;
+ NETSCAPE_SPKI *spki=NULL;
+ char * password, * spkstr;
+ long keyresource = -1;
+ const char *spkac = "SPKAC=";
+
+ 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);
+
+ if (pkey == NULL) {
+ goto cleanup;
+ }
+
+ if ((spki = NETSCAPE_SPKI_new()) == NULL) {
+ goto cleanup;
+ }
+
+ if (password) {
+ ASN1_STRING_set(spki->spkac->challenge, password, (int)strlen(password));
+ }
+
+ if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
+ goto cleanup;
+ }
+
+ if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_md5())) {
+ goto cleanup;
+ }
+
+ spkstr = NETSCAPE_SPKI_b64_encode(spki);
+
+ char * s = malloc(snprintf(NULL, 0, "%s%s", spkac, spkstr));
+ sprintf(s, "%s%s", spkac, spkstr);
+
+ if (strlen(s)>0) {
+ RETVAL_STRINGL(s, strlen(s), 0);
+ } else {
+ RETURN_FALSE;
+ }
+
+cleanup:
+ if (keyresource == -1 && pkey) {
+ NETSCAPE_SPKI_free(spki);
+ EVP_PKEY_free(pkey);
+ }
+ if (spkstr) {
+ OPENSSL_free(spkstr);
+ }
+}
+/* }}} */
+
+/* {{{ proto bool openssl_spki_verify(string spki)
+ Verifies spki returns boolean */
+PHP_FUNCTION(openssl_spki_verify)
+{
+ int spkstr_len, i, x=0;
+ char *spkstr = NULL;
+ 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;
+ }
+
+ if (!spkstr) {
+ goto cleanup;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
+ if (!spki) {
+ goto cleanup;
+ }
+
+ pkey = NETSCAPE_SPKI_get_pubkey(spki);
+ if (pkey == NULL) {
+ goto cleanup;
+ }
+
+ i = NETSCAPE_SPKI_verify(spki, pkey);
+
+ if (i > 0) {
+ x = 1;
+ }
+ goto cleanup;
+
+cleanup:
+ if (spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (pkey) {
+ EVP_PKEY_free(pkey);
+ }
+ RETURN_BOOL(x);
+}
+/* }}} */
+
+/* {{{ proto string openssl_spki_export(string spki)
+ Exports public key from existing spki to var */
+PHP_FUNCTION(openssl_spki_export)
+{
+ int spkstr_len;
+ EVP_PKEY *pkey = NULL;
+ NETSCAPE_SPKI *spki = NULL;
+ BIO *out = BIO_new_fp(stdout, BIO_CLOSE);
+ char *spkstr;
+
+ 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) {
+ goto cleanup;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr, strlen(spkstr));
+ if (!spki) {
+ goto cleanup;
+ }
+
+ pkey = NETSCAPE_SPKI_get_pubkey(spki);
+ if (!pkey) {
+ goto cleanup;
+ }
+
+ PEM_write_bio_PUBKEY(out, pkey);
+
+cleanup:
+ if (spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (out) {
+ BIO_free_all(out);
+ }
+ if (pkey) {
+ EVP_PKEY_free(pkey);
+ }
+}
+/* }}} */
+
+/* {{{ proto string openssl_spki_details(string spki)
+ Provides details from existing spki to var */
+PHP_FUNCTION(openssl_spki_details)
+{
+ BUF_MEM *buf;
+ int spkstr_len;
+ NETSCAPE_SPKI *spki = NULL;
+ BIO *out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ char *spkstr;
+
+ 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) {
+ goto cleanup;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr, strlen(spkstr));
+ if (!spki) {
+ goto cleanup;
+ }
+
+ NETSCAPE_SPKI_print(out, spki);
+
+cleanup:
+ if (spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (out) {
+ BIO_free_all(out);
+ }
+}
+/* }}} */
+
/* {{{ 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
+++ php-5.3.8/ext/openssl/php_openssl.h
@@ -74,6 +74,11 @@
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_details);
#else
#define phpext_openssl_ptr NULL
|