Change the treatment of stdin and stdout to allow binary data
authorRichard Levitte <levitte@openssl.org>
Sun, 6 Sep 2015 10:20:12 +0000 (12:20 +0200)
committerRichard Levitte <levitte@openssl.org>
Sun, 6 Sep 2015 11:34:49 +0000 (13:34 +0200)
If the output to stdout or the input from stdin is meant to be binary,
it's deeply unsetting to get the occasional LF converted to CRLF or
the other way around.  If someone happens to forget to redirect stdin
or stdout, they will get gibberish anyway, line ending conversion will
not change that.

Therefore, let's not have dup_bio_* decide unilaterally what mode the
BIO derived from stdin and stdout, and rather let the app decide by
declaring the intended format.

Reviewed-by: Tim Hudson <tjh@openssl.org>
apps/apps.c
apps/apps.h
apps/enc.c
apps/engine.c
apps/openssl.c
apps/s_client.c
apps/s_server.c

index 0b5f9fd062b041d56bd636b26d695907a8bf0898..d4af862a18580ea0cac9a173da91684ae2c11963 100644 (file)
@@ -470,7 +470,7 @@ static char *app_get_pass(char *arg, int keepbio)
             pwdbio = BIO_push(btmp, pwdbio);
 #endif
         } else if (strcmp(arg, "stdin") == 0) {
-            pwdbio = dup_bio_in();
+            pwdbio = dup_bio_in(FORMAT_TEXT);
             if (!pwdbio) {
                 BIO_printf(bio_err, "Can't open BIO for stdin\n");
                 return NULL;
@@ -687,7 +687,7 @@ X509 *load_cert(const char *file, int format,
 
     if (file == NULL) {
         unbuffer(stdin);
-        cert = dup_bio_in();
+        cert = dup_bio_in(format);
     } else
         cert = bio_open_default(file, 'r', format);
     if (cert == NULL)
@@ -776,7 +776,7 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
 #endif
     if (file == NULL && maybe_stdin) {
         unbuffer(stdin);
-        key = dup_bio_in();
+        key = dup_bio_in(format);
     } else
         key = bio_open_default(file, 'r', format);
     if (key == NULL)
@@ -839,7 +839,7 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
 #endif
     if (file == NULL && maybe_stdin) {
         unbuffer(stdin);
-        key = dup_bio_in();
+        key = dup_bio_in(format);
     } else
         key = bio_open_default(file, 'r', format);
     if (key == NULL)
@@ -2721,16 +2721,24 @@ int raw_write_stdout(const void *buf, int siz)
  * does impact behavior on some platform, such as differentiating between
  * text and binary input/output on non-Unix platforms
  */
-BIO *dup_bio_in(void)
+inline int istext(int format)
 {
-    return BIO_new_fp(stdin, BIO_NOCLOSE | BIO_FP_TEXT);
+    return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT;
 }
 
-BIO *dup_bio_out(void)
+BIO *dup_bio_in(int format)
 {
-    BIO *b = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+    return BIO_new_fp(stdin,
+                      BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
+}
+
+BIO *dup_bio_out(int format)
+{
+    BIO *b = BIO_new_fp(stdout,
+                        BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
 #ifdef OPENSSL_SYS_VMS
-    b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
+    if (istext(format))
+        b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
 #endif
     return b;
 }
@@ -2746,11 +2754,11 @@ static const char *modestr(char mode, int format)
 
     switch (mode) {
     case 'a':
-        return (format & B_FORMAT_TEXT) ? "a" : "ab";
+        return istext(format) ? "a" : "ab";
     case 'r':
-        return (format & B_FORMAT_TEXT) ? "r" : "rb";
+        return istext(format) ? "r" : "rb";
     case 'w':
-        return (format & B_FORMAT_TEXT) ? "w" : "wb";
+        return istext(format) ? "w" : "wb";
     }
     /* The assert above should make sure we never reach this point */
     return NULL;
@@ -2788,7 +2796,7 @@ BIO *bio_open_owner(const char *filename, int format, int private)
 #ifdef O_TRUNC
     mode |= O_TRUNC;
 #endif
-    binmode = !(format & B_FORMAT_TEXT);
+    binmode = istext(format);
     if (binmode) {
 #ifdef O_BINARY
         mode |= O_BINARY;
@@ -2828,7 +2836,7 @@ static BIO *bio_open_default_(const char *filename, char mode, int format,
     BIO *ret;
 
     if (filename == NULL || strcmp(filename, "-") == 0) {
-        ret = mode == 'r' ? dup_bio_in() : dup_bio_out();
+        ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format);
         if (quiet) {
             ERR_clear_error();
             return ret;
index c34d22ed1dbb10801acc1fc71810aa45d95cd1d5..0901c7dce3c721f76d058d1a4e88920c63f2d450 100644 (file)
@@ -152,8 +152,8 @@ extern char *default_config_file;
 extern BIO *bio_in;
 extern BIO *bio_out;
 extern BIO *bio_err;
-BIO *dup_bio_in(void);
-BIO *dup_bio_out(void);
+BIO *dup_bio_in(int format);
+BIO *dup_bio_out(int format);
 BIO *bio_open_owner(const char *filename, int format, int private);
 BIO *bio_open_default(const char *filename, char mode, int format);
 BIO *bio_open_default_quiet(const char *filename, char mode, int format);
index 0bdba381617f5c564c51e1bba7bd8e93aa71e145..fc7e14c65cbfba70e521b9d65523338300535b4d 100644 (file)
@@ -328,7 +328,7 @@ int enc_main(int argc, char **argv)
 
     if (infile == NULL) {
         unbuffer(stdin);
-        in = dup_bio_in();
+        in = dup_bio_in(format);
     } else
         in = bio_open_default(infile, 'r', format);
     if (in == NULL)
index 91af7bff72e17f936dca42ed5f38c049c148b2d8..b1c13715287831aae676e8537ab57a87ca106dfb 100644 (file)
@@ -319,7 +319,7 @@ int engine_main(int argc, char **argv)
     OPTION_CHOICE o;
     char *prog;
 
-    out = dup_bio_out();
+    out = dup_bio_out(FORMAT_TEXT);
     prog = opt_init(argc, argv, engine_options);
     if (!engines || !pre_cmds || !post_cmds)
         goto end;
index 0208289fb6a655fbe15cd0888ac0f4fdce68a213..39ae64d49848f0b5a31785ccae64e4b926c6ac22 100644 (file)
@@ -293,8 +293,8 @@ int main(int argc, char *argv[])
 
     /* Set up some of the environment. */
     default_config_file = make_config_name();
-    bio_in = dup_bio_in();
-    bio_out = dup_bio_out();
+    bio_in = dup_bio_in(FORMAT_TEXT);
+    bio_out = dup_bio_out(FORMAT_TEXT);
     bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
 
 #if defined( OPENSSL_SYS_VMS)
index 819cff344a747688292306344f1877ae21a050b0..3eb495a47901a4ef09e49db1e56c2c7826f2450f 100644 (file)
@@ -1162,9 +1162,9 @@ int s_client_main(int argc, char **argv)
         if (c_quiet && !c_debug) {
             bio_c_out = BIO_new(BIO_s_null());
             if (c_msg && !bio_c_msg)
-                bio_c_msg = dup_bio_out();
+                bio_c_msg = dup_bio_out(FORMAT_TEXT);
         } else if (bio_c_out == NULL)
-            bio_c_out = dup_bio_out();
+            bio_c_out = dup_bio_out(FORMAT_TEXT);
     }
 #ifndef OPENSSL_NO_SRP
     if (!app_passwd(srppass, NULL, &srp_arg.srppassin, NULL)) {
index e7c794c2a5ea5816c65faee5cc935ed7661f3f27..8fe1ebe224e4139f52435a7d13c1805ca7c83af8 100644 (file)
@@ -1575,10 +1575,10 @@ int s_server_main(int argc, char *argv[])
         if (s_quiet && !s_debug) {
             bio_s_out = BIO_new(BIO_s_null());
             if (s_msg && !bio_s_msg)
-                bio_s_msg = dup_bio_out();
+                bio_s_msg = dup_bio_out(FORMAT_TEXT);
         } else {
             if (bio_s_out == NULL)
-                bio_s_out = dup_bio_out();
+                bio_s_out = dup_bio_out(FORMAT_TEXT);
         }
     }
 #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)