I find having to encrypt to and from a file quite a pain. I create a message
in PHP, save it to a temporary file, encrypt it to a second temporary file,
read this file, then mail the contents. If you are working with the message,
either before or after encryption, in PHP then this process clearly contains
more effort than it needs to. Also, writing the plain text message to disk
and then deleting it with the unlink, isn't all that secure.

This patch allows you to supply the message to encrypt as a string, and
allows you to get back the encrypted message as a string. Of course it is
still possible to use files if you prefer (by specifying files with the
"file://" prefix, as used by the certificate parameter).  It's fairly
simple, and should probably be applied to other functions in this extension
too. If people like it, I'd be happy to do the same to these functions.

As I see it there are three potential problems with this patch:
1) Changes default behaviour (people wanting to use files would need to add
"file://" to their filenames), so would be best added at a major version.
2) Encrypting a message from memory may not be binary safe (output to memory
will always be binary safe).
3) It's my first patch, so it may not be perfect. I'm happy to accept
criticism.

Richard.
Index: ext/openssl/openssl.c
===================================================================
RCS file: /repository/php-src/ext/openssl/openssl.c,v
retrieving revision 1.84
diff -u -r1.84 openssl.c
--- ext/openssl/openssl.c       13 Oct 2003 11:43:11 -0000      1.84
+++ ext/openssl/openssl.c       5 Nov 2003 09:02:43 -0000
@@ -2203,11 +2203,11 @@
 }
 /* }}} */
 
-/* {{{ proto bool openssl_pkcs7_encrypt(string infile, string outfile, mixed 
recipcerts, array headers [, long flags [, long cipher]])
+/* {{{ proto bool openssl_pkcs7_encrypt(string message, &string encrypted, mixed 
recipcerts, array headers [, long flags [, long cipher]])
    Encrypts the message in the file named infile with the certificates in recipcerts 
and output the result to the file named outfile */
 PHP_FUNCTION(openssl_pkcs7_encrypt)
 {
-       zval * zrecipcerts, * zheaders = NULL;
+       zval * zrecipcerts, * zheaders = NULL, * zoutput = NULL, * zinput = NULL;
        STACK_OF(X509) * recipcerts = NULL;
        BIO * infile = NULL, * outfile = NULL;
        long flags = 0;
@@ -2217,32 +2217,47 @@
        X509 * cert;
        const EVP_CIPHER *cipher = NULL;
        long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
-       uint strindexlen;
+       uint strindexlen, len = 0;
        ulong intindex;
        char * strindex;
-       char * infilename = NULL;       int infilename_len;
-       char * outfilename = NULL;      int outfilename_len;
+       char * infilename = NULL;
+       char * outfilename = NULL;
+       BOOL outfilemode = FALSE;
+       char * buffer = NULL;
        
        RETVAL_FALSE;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssza!|ll", &infilename, 
&infilename_len,
-                               &outfilename, &outfilename_len, &zrecipcerts, 
&zheaders, &flags, &cipherid) == FAILURE)
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzza!|ll", &zinput, 
&zoutput,
+                               &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
                return;
 
-       
-       if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || 
php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {
-               return;
+       convert_to_string_ex(&zinput);
+       convert_to_string_ex(&zoutput);
+
+       if (Z_STRLEN_PP(&zinput) > 7 && memcmp(Z_STRVAL_PP(&zinput), "file://", 7) == 
0) {
+               infilename = Z_STRVAL_PP(&zinput) + 7;
+               if (php_openssl_safe_mode_chk(infilename TSRMLS_CC))
+                       return;
+               infile = BIO_new_file(infilename, "r");
+       } else {
+               infile = BIO_new_mem_buf(Z_STRVAL_PP(&zinput), Z_STRLEN_PP(&zinput));
        }
 
-       infile = BIO_new_file(infilename, "r");
-       if (infile == NULL) {
+       if (infile == NULL)
                goto clean_exit;
+
+       if (Z_STRLEN_PP(&zoutput) > 7 && memcmp(Z_STRVAL_PP(&zoutput), "file://", 7) 
== 0) {
+               outfilemode = TRUE;
+               outfilename = Z_STRVAL_PP(&zoutput) + 7;
+               if (php_openssl_safe_mode_chk(outfilename TSRMLS_CC))
+                       return;
+               outfile = BIO_new_file(outfilename, "w");
+       } else {
+               outfile = BIO_new(BIO_s_mem());
        }
 
-       outfile = BIO_new_file(outfilename, "w");
-       if (outfile == NULL) { 
+       if (outfile == NULL)
                goto clean_exit;
-       }
 
        recipcerts = sk_X509_new_null();
 
@@ -2344,6 +2359,15 @@
 
        /* write the encrypted data */
        SMIME_write_PKCS7(outfile, p7, infile, flags);
+
+       if (!outfilemode) {
+               zval_dtor(zoutput);
+               len = BIO_ctrl_pending(outfile);
+               buffer = emalloc(len+1);
+               BIO_read(outfile, buffer, len);
+               buffer[len] = '\0';
+               ZVAL_STRINGL(zoutput, buffer, len, 0);
+       }
 
        RETVAL_TRUE;
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to