cellog Fri Jun 13 20:15:19 2008 UTC Modified files: (Branch: PHP_5_3) /php-src/ext/phar phar.c phar.phar phar_internal.h phar_object.c util.c Log: full refactor of signatures complete - now to implement them for tar as a starting point
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar.c?r1=1.370.2.14&r2=1.370.2.15&diff_format=u Index: php-src/ext/phar/phar.c diff -u php-src/ext/phar/phar.c:1.370.2.14 php-src/ext/phar/phar.c:1.370.2.15 --- php-src/ext/phar/phar.c:1.370.2.14 Fri Jun 13 13:06:46 2008 +++ php-src/ext/phar/phar.c Fri Jun 13 20:15:19 2008 @@ -17,32 +17,13 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar.c,v 1.370.2.14 2008/06/13 13:06:46 felipe Exp $ */ +/* $Id: phar.c,v 1.370.2.15 2008/06/13 20:15:19 cellog Exp $ */ #define PHAR_MAIN 1 #include "phar_internal.h" #include "SAPI.h" #include "func_interceptors.h" -#ifdef PHAR_HAVE_OPENSSL - -/* OpenSSL includes */ -#include <openssl/evp.h> -#include <openssl/x509.h> -#include <openssl/x509v3.h> -#include <openssl/crypto.h> -#include <openssl/pem.h> -#include <openssl/err.h> -#include <openssl/conf.h> -#include <openssl/rand.h> -#include <openssl/ssl.h> -#include <openssl/pkcs12.h> - -#endif - -#ifndef PHAR_HAVE_OPENSSL -static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end, char *key, int key_len, char **signature, int *signature_len TSRMLS_DC); -#endif static void destroy_phar_data(void *pDest); ZEND_DECLARE_MODULE_GLOBALS(phar) @@ -604,25 +585,6 @@ } /* }}}*/ -static const char hexChars[] = "0123456789ABCDEF"; - -static int phar_hex_str(const char *digest, size_t digest_len, char ** signature) -{ - int pos = -1; - size_t len = 0; - - TSRMLS_FETCH(); - - *signature = (char*)safe_pemalloc(digest_len, 2, 1, PHAR_G(persist)); - - for (; len < digest_len; ++len) { - (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] >> 4]; - (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] & 0x0F]; - } - (*signature)[++pos] = '\0'; - return pos; -} - /** * Does not check for a previously opened phar in the cache. * @@ -2917,169 +2879,57 @@ /* append signature */ if (global_flags & PHAR_HDR_SIGNATURE) { - unsigned char buf[1024]; - int sig_flags = 0, sig_len; char sig_buf[4]; + php_stream_rewind(newfile); - if (phar->signature) { efree(phar->signature); phar->signature = NULL; } switch(phar->sig_flags) { -#if HAVE_HASH_EXT - case PHAR_SIG_SHA512: { - unsigned char digest[64]; - PHP_SHA512_CTX context; - - PHP_SHA512Init(&context); - while ((sig_len = php_stream_read(newfile, (char*)buf, sizeof(buf))) > 0) { - PHP_SHA512Update(&context, buf, sig_len); - } - PHP_SHA512Final(digest, &context); - php_stream_write(newfile, (char *) digest, sizeof(digest)); - sig_flags |= PHAR_SIG_SHA512; - phar->sig_len = phar_hex_str((const char*)digest, sizeof(digest), &phar->signature); - break; - } - case PHAR_SIG_SHA256: { - unsigned char digest[32]; - PHP_SHA256_CTX context; - - PHP_SHA256Init(&context); - while ((sig_len = php_stream_read(newfile, (char*)buf, sizeof(buf))) > 0) { - PHP_SHA256Update(&context, buf, sig_len); - } - PHP_SHA256Final(digest, &context); - php_stream_write(newfile, (char *) digest, sizeof(digest)); - sig_flags |= PHAR_SIG_SHA256; - phar->sig_len = phar_hex_str((const char*)digest, sizeof(digest), &phar->signature); - break; - } -#else - case PHAR_SIG_SHA512: - case PHAR_SIG_SHA256: - if (closeoldfile) { - php_stream_close(oldfile); - } - php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\" with requested hash type", entry->filename, phar->fname); - } - return EOF; -#endif - case PHAR_SIG_OPENSSL: { - int siglen; - unsigned char *sigbuf; -#ifdef PHAR_HAVE_OPENSSL - BIO *in; - EVP_PKEY *key; - EVP_MD *mdtype = (EVP_MD *) EVP_sha1(); - EVP_MD_CTX md_ctx; - - if (!zend_hash_exists(&module_registry, "openssl", sizeof("openssl"))) { +#if !HAVE_HASH_EXT + case PHAR_SIG_SHA512: + case PHAR_SIG_SHA256: if (closeoldfile) { php_stream_close(oldfile); } php_stream_close(newfile); if (error) { - spprintf(error, 0, "phar \"%s\" openssl signature cannot be created, openssl not loaded", phar->fname); + spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\" with requested hash type", entry->filename, phar->fname); } return EOF; - } - in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len)); +#endif + default: { + char *digest; + int digest_len; - if (in == NULL) { - if (closeoldfile) { - php_stream_close(oldfile); - } - php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\" with requested openssl signature", entry->filename, phar->fname); + if (FAILURE == phar_create_signature(phar, newfile, &digest, &digest_len, error TSRMLS_CC)) { + if (error) { + char *save = *error; + spprintf(error, 0, "phar error: unable to write signature: %s", save); + efree(save); + } + efree(digest); + if (closeoldfile) { + php_stream_close(oldfile); + } + php_stream_close(newfile); + return EOF; } - return EOF; - } - key = PEM_read_bio_PrivateKey(in, NULL,NULL, ""); - BIO_free(in); - siglen = EVP_PKEY_size(key); - sigbuf = emalloc(siglen + 1); - - EVP_SignInit(&md_ctx, mdtype); - while ((sig_len = php_stream_read(newfile, (char*)buf, sizeof(buf))) > 0) { - EVP_SignUpdate(&md_ctx, buf, sig_len); - } - if (!EVP_SignFinal (&md_ctx, sigbuf,(unsigned int *)&siglen, key)) { - efree(sigbuf); - if (closeoldfile) { - php_stream_close(oldfile); - } - php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); + php_stream_write(newfile, digest, digest_len); + efree(digest); + if (phar->sig_flags == PHAR_SIG_OPENSSL) { + phar_set_32(sig_buf, digest_len); + php_stream_write(newfile, sig_buf, 4); } - return EOF; + break; } - sigbuf[siglen] = '\0'; - EVP_MD_CTX_cleanup(&md_ctx); -#else - sigbuf = NULL; - siglen = 0; - php_stream_seek(newfile, 0, SEEK_END); - if (FAILURE == phar_call_openssl_signverify(1, newfile, php_stream_tell(newfile), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen TSRMLS_CC)) { - if (closeoldfile) { - php_stream_close(oldfile); - } - php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); - } - return EOF; - } -#endif - sig_flags |= PHAR_SIG_OPENSSL; - phar->sig_len = phar_hex_str((const char *)sigbuf, siglen, &phar->signature); - php_stream_write(newfile, (char *) sigbuf, siglen); - efree(sigbuf); - phar_set_32(sig_buf, siglen); - php_stream_write(newfile, sig_buf, 4); - } - break; - default: - case PHAR_SIG_SHA1: { - unsigned char digest[20]; - PHP_SHA1_CTX context; - - PHP_SHA1Init(&context); - while ((sig_len = php_stream_read(newfile, (char*)buf, sizeof(buf))) > 0) { - PHP_SHA1Update(&context, buf, sig_len); - } - PHP_SHA1Final(digest, &context); - php_stream_write(newfile, (char *) digest, sizeof(digest)); - sig_flags |= PHAR_SIG_SHA1; - phar->sig_len = phar_hex_str((const char*)digest, sizeof(digest), &phar->signature); - break; - } - case PHAR_SIG_MD5: { - unsigned char digest[16]; - PHP_MD5_CTX context; - - PHP_MD5Init(&context); - while ((sig_len = php_stream_read(newfile, (char*)buf, sizeof(buf))) > 0) { - PHP_MD5Update(&context, buf, sig_len); - } - PHP_MD5Final(digest, &context); - php_stream_write(newfile, (char *) digest, sizeof(digest)); - sig_flags |= PHAR_SIG_MD5; - phar->sig_len = phar_hex_str((const char*)digest, sizeof(digest), &phar->signature); - break; - } } - phar_set_32(sig_buf, sig_flags); + phar_set_32(sig_buf, phar->sig_flags); php_stream_write(newfile, sig_buf, 4); php_stream_write(newfile, "GBMB", 4); - phar->sig_flags = sig_flags; } /* finally, close the temp file, rename the original phar, @@ -3535,7 +3385,7 @@ php_info_print_table_header(2, "Phar: PHP Archive support", "enabled"); php_info_print_table_row(2, "Phar EXT version", PHP_PHAR_VERSION); php_info_print_table_row(2, "Phar API version", PHP_PHAR_API_VERSION); - php_info_print_table_row(2, "CVS revision", "$Revision: 1.370.2.14 $"); + php_info_print_table_row(2, "CVS revision", "$Revision: 1.370.2.15 $"); php_info_print_table_row(2, "Phar-based phar archives", "enabled"); php_info_print_table_row(2, "Tar-based phar archives", "enabled"); php_info_print_table_row(2, "ZIP-based phar archives", "enabled"); http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar.phar?r1=1.7.2.12&r2=1.7.2.13&diff_format=u Index: php-src/ext/phar/phar.phar http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar_internal.h?r1=1.109.2.9&r2=1.109.2.10&diff_format=u Index: php-src/ext/phar/phar_internal.h diff -u php-src/ext/phar/phar_internal.h:1.109.2.9 php-src/ext/phar/phar_internal.h:1.109.2.10 --- php-src/ext/phar/phar_internal.h:1.109.2.9 Fri Jun 13 15:59:13 2008 +++ php-src/ext/phar/phar_internal.h Fri Jun 13 20:15:19 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_internal.h,v 1.109.2.9 2008/06/13 15:59:13 cellog Exp $ */ +/* $Id: phar_internal.h,v 1.109.2.10 2008/06/13 20:15:19 cellog Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -421,6 +421,7 @@ int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char *alias, int alias_len, char **error TSRMLS_DC); int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC); int phar_verify_signature(php_stream *fp, size_t end_of_phar, int sig_type, char *sig, int sig_len, char *fname, char **signature, int *signature_len, char **error TSRMLS_DC); +int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, int *signature_length, char **error TSRMLS_DC); /* utility functions */ char *phar_create_default_stub(const char *index_php, const char *web_index, size_t *len, char **error TSRMLS_DC); http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar_object.c?r1=1.266.2.17&r2=1.266.2.18&diff_format=u Index: php-src/ext/phar/phar_object.c diff -u php-src/ext/phar/phar_object.c:1.266.2.17 php-src/ext/phar/phar_object.c:1.266.2.18 --- php-src/ext/phar/phar_object.c:1.266.2.17 Tue Jun 10 19:20:33 2008 +++ php-src/ext/phar/phar_object.c Fri Jun 13 20:15:19 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_object.c,v 1.266.2.17 2008/06/10 19:20:33 cellog Exp $ */ +/* $Id: phar_object.c,v 1.266.2.18 2008/06/13 20:15:19 cellog Exp $ */ #include "phar_internal.h" #include "func_interceptors.h" @@ -2759,6 +2759,9 @@ PHAR_ARCHIVE_OBJECT(); if (phar_obj->arc.archive->signature) { + char *unknown; + int unknown_len; + array_init(return_value); add_assoc_stringl(return_value, "hash", phar_obj->arc.archive->signature, phar_obj->arc.archive->sig_len, 1); switch(phar_obj->arc.archive->sig_flags) { @@ -2777,6 +2780,10 @@ case PHAR_SIG_OPENSSL: add_assoc_stringl(return_value, "hash_type", "OpenSSL", 7, 1); break; + default: + unknown_len = spprintf(&unknown, 0, "Unknown (%d)", phar_obj->arc.archive->sig_flags); + add_assoc_stringl(return_value, "hash_type", unknown, unknown_len, 0); + break; } } else { RETURN_FALSE; http://cvs.php.net/viewvc.cgi/php-src/ext/phar/util.c?r1=1.55.2.6&r2=1.55.2.7&diff_format=u Index: php-src/ext/phar/util.c diff -u php-src/ext/phar/util.c:1.55.2.6 php-src/ext/phar/util.c:1.55.2.7 --- php-src/ext/phar/util.c:1.55.2.6 Fri Jun 13 13:06:46 2008 +++ php-src/ext/phar/util.c Fri Jun 13 20:15:19 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: util.c,v 1.55.2.6 2008/06/13 13:06:46 felipe Exp $ */ +/* $Id: util.c,v 1.55.2.7 2008/06/13 20:15:19 cellog Exp $ */ #include "phar_internal.h" #ifdef PHAR_HAVE_OPENSSL @@ -1340,12 +1340,10 @@ static const char hexChars[] = "0123456789ABCDEF"; -static int phar_hex_str(const char *digest, size_t digest_len, char ** signature) +static int phar_hex_str(const char *digest, size_t digest_len, char **signature TSRMLS_DC) { int pos = -1; size_t len = 0; - - TSRMLS_FETCH(); *signature = (char*)safe_pemalloc(digest_len, 2, 1, PHAR_G(persist)); @@ -1568,7 +1566,7 @@ EVP_MD_CTX_cleanup(&md_ctx); #endif - *signature_len = phar_hex_str((const char*)sig, sig_len, signature); + *signature_len = phar_hex_str((const char*)sig, sig_len, signature TSRMLS_CC); } break; #if HAVE_HASH_EXT @@ -1599,7 +1597,7 @@ return FAILURE; } - *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature); + *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature TSRMLS_CC); break; } case PHAR_SIG_SHA256: { @@ -1629,7 +1627,7 @@ return FAILURE; } - *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature); + *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature TSRMLS_CC); break; } #else @@ -1667,7 +1665,7 @@ return FAILURE; } - *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature); + *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature TSRMLS_CC); break; } case PHAR_SIG_MD5: { @@ -1697,7 +1695,7 @@ return FAILURE; } - *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature); + *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature TSRMLS_CC); break; } default: @@ -1709,3 +1707,142 @@ return SUCCESS; } /* }}} */ + +int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, int *signature_length, char **error TSRMLS_DC) /* {{{ */ +{ + unsigned char buf[1024]; + int sig_len; + + php_stream_rewind(fp); + + if (phar->signature) { + efree(phar->signature); + phar->signature = NULL; + } + + switch(phar->sig_flags) { +#if HAVE_HASH_EXT + case PHAR_SIG_SHA512: { + unsigned char digest[64]; + PHP_SHA512_CTX context; + + PHP_SHA512Init(&context); + while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { + PHP_SHA512Update(&context, buf, sig_len); + } + PHP_SHA512Final(digest, &context); + *signature = estrndup((char *) digest, 64); + *signature_length = 64; + break; + } + case PHAR_SIG_SHA256: { + unsigned char digest[32]; + PHP_SHA256_CTX context; + + PHP_SHA256Init(&context); + while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { + PHP_SHA256Update(&context, buf, sig_len); + } + PHP_SHA256Final(digest, &context); + *signature = estrndup((char *) digest, 32); + *signature_length = 32; + break; + } +#else + case PHAR_SIG_SHA512: + case PHAR_SIG_SHA256: + if (error) { + spprintf(error, 0, "unable to write to phar \"%s\" with requested hash type", phar->fname); + } + return FAILURE; +#endif + case PHAR_SIG_OPENSSL: { + int siglen; + unsigned char *sigbuf; +#ifdef PHAR_HAVE_OPENSSL + BIO *in; + EVP_PKEY *key; + EVP_MD *mdtype = (EVP_MD *) EVP_sha1(); + EVP_MD_CTX md_ctx; + + if (!zend_hash_exists(&module_registry, "openssl", sizeof("openssl"))) { + if (error) { + spprintf(error, 0, "phar \"%s\" openssl signature cannot be created, openssl not loaded", phar->fname); + } + return FAILURE; + } + in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len)); + + if (in == NULL) { + if (error) { + spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", phar->fname); + } + return FAILURE; + } + key = PEM_read_bio_PrivateKey(in, NULL,NULL, ""); + + BIO_free(in); + siglen = EVP_PKEY_size(key); + sigbuf = emalloc(siglen + 1); + + EVP_SignInit(&md_ctx, mdtype); + while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { + EVP_SignUpdate(&md_ctx, buf, sig_len); + } + if (!EVP_SignFinal (&md_ctx, sigbuf,(unsigned int *)&siglen, key)) { + efree(sigbuf); + if (error) { + spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); + } + return FAILURE; + } + sigbuf[siglen] = '\0'; + EVP_MD_CTX_cleanup(&md_ctx); +#else + sigbuf = NULL; + siglen = 0; + php_stream_seek(fp, 0, SEEK_END); + if (FAILURE == phar_call_openssl_signverify(1, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen TSRMLS_CC)) { + if (error) { + spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); + } + return FAILURE; + } +#endif + *signature = (char *) sigbuf; + *signature_length = siglen; + } + break; + default: + phar->sig_flags = PHAR_SIG_SHA1; + case PHAR_SIG_SHA1: { + unsigned char digest[20]; + PHP_SHA1_CTX context; + + PHP_SHA1Init(&context); + while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { + PHP_SHA1Update(&context, buf, sig_len); + } + PHP_SHA1Final(digest, &context); + *signature = estrndup((char *) digest, 20); + *signature_length = 20; + break; + } + case PHAR_SIG_MD5: { + unsigned char digest[16]; + PHP_MD5_CTX context; + + PHP_MD5Init(&context); + while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { + PHP_MD5Update(&context, buf, sig_len); + } + PHP_MD5Final(digest, &context); + *signature = estrndup((char *) digest, 16); + *signature_length = 16; + break; + } + } + phar->sig_len = phar_hex_str((const char *)*signature, *signature_length, &phar->signature TSRMLS_CC); + return SUCCESS; +} +/* }}} */
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php