DSA mod inverse fix
[openssl.git] / crypto / bio / bss_file.c
index 1da6b861810cac44cc9aa5e236833e6a2ec85fe1..8de2391267afe8d9d2b33edb03b0750ee12c1d46 100644 (file)
@@ -1,65 +1,10 @@
-/* crypto/bio/bss_file.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
  *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/*-
- * 03-Dec-1997  rdenny@dc3.com  Fix bug preventing use of stdin/stdout
- *              with binary data (e.g. asn1parse -inform DER < xxx) under
- *              Windows
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
  */
 
 #ifndef HEADER_BSS_FILE_C
 
 # include <stdio.h>
 # include <errno.h>
-# include "cryptlib.h"
 # include "bio_lcl.h"
 # include <openssl/err.h>
 
-# if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
-#  include <nwfileio.h>
-# endif
-
 # if !defined(OPENSSL_NO_STDIO)
 
 static int file_write(BIO *h, const char *buf, int num);
@@ -102,86 +42,54 @@ static int file_gets(BIO *h, char *str, int size);
 static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 static int file_new(BIO *h);
 static int file_free(BIO *data);
-static BIO_METHOD methods_filep = {
+static const BIO_METHOD methods_filep = {
     BIO_TYPE_FILE,
     "FILE pointer",
+    /* TODO: Convert to new style write function */
+    bwrite_conv,
     file_write,
+    /* TODO: Convert to new style read function */
+    bread_conv,
     file_read,
     file_puts,
     file_gets,
     file_ctrl,
     file_new,
     file_free,
-    NULL,
+    NULL,                      /* file_callback_ctrl */
 };
 
 BIO *BIO_new_file(const char *filename, const char *mode)
 {
-    BIO *ret;
-    FILE *file = NULL;
-
-#  if defined(_WIN32) && defined(CP_UTF8)
-    int sz, len_0 = (int)strlen(filename) + 1;
-    DWORD flags;
-
-    /*
-     * Basically there are three cases to cover: a) filename is
-     * pure ASCII string; b) actual UTF-8 encoded string and
-     * c) locale-ized string, i.e. one containing 8-bit
-     * characters that are meaningful in current system locale.
-     * If filename is pure ASCII or real UTF-8 encoded string,
-     * MultiByteToWideChar succeeds and _wfopen works. If
-     * filename is locale-ized string, chances are that
-     * MultiByteToWideChar fails reporting
-     * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
-     * back to fopen...
-     */
-    if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
-                                  filename, len_0, NULL, 0)) > 0 ||
-        (GetLastError() == ERROR_INVALID_FLAGS &&
-         (sz = MultiByteToWideChar(CP_UTF8, (flags = 0),
-                                   filename, len_0, NULL, 0)) > 0)
-        ) {
-        WCHAR wmode[8];
-        WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
-
-        if (MultiByteToWideChar(CP_UTF8, flags,
-                                filename, len_0, wfilename, sz) &&
-            MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1,
-                                wmode, OSSL_NELEM(wmode)) &&
-            (file = _wfopen(wfilename, wmode)) == NULL &&
-            (errno == ENOENT || errno == EBADF)
-            ) {
-            /*
-             * UTF-8 decode succeeded, but no file, filename
-             * could still have been locale-ized...
-             */
-            file = fopen(filename, mode);
-        }
-    } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
-        file = fopen(filename, mode);
-    }
-#  else
-    file = fopen(filename, mode);
-#  endif
+    BIO  *ret;
+    FILE *file = openssl_fopen(filename, mode);
+    int fp_flags = BIO_CLOSE;
+
+    if (strchr(mode, 'b') == NULL)
+        fp_flags |= BIO_FP_TEXT;
+
     if (file == NULL) {
         SYSerr(SYS_F_FOPEN, get_last_sys_error());
         ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
-        if (errno == ENOENT)
+        if (errno == ENOENT
+# ifdef ENXIO
+            || errno == ENXIO
+# endif
+            )
             BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
         else
             BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
-        return (NULL);
+        return NULL;
     }
     if ((ret = BIO_new(BIO_s_file())) == NULL) {
         fclose(file);
-        return (NULL);
+        return NULL;
     }
 
     BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
                                              * UPLINK */
-    BIO_set_fp(ret, file, BIO_CLOSE);
-    return (ret);
+    BIO_set_fp(ret, file, fp_flags);
+    return ret;
 }
 
 BIO *BIO_new_fp(FILE *stream, int close_flag)
@@ -189,17 +97,17 @@ BIO *BIO_new_fp(FILE *stream, int close_flag)
     BIO *ret;
 
     if ((ret = BIO_new(BIO_s_file())) == NULL)
-        return (NULL);
+        return NULL;
 
-    BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for
-                                           * documentation puposes */
+    /* redundant flag, left for documentation purposes */
+    BIO_set_flags(ret, BIO_FLAGS_UPLINK);
     BIO_set_fp(ret, stream, close_flag);
-    return (ret);
+    return ret;
 }
 
-BIO_METHOD *BIO_s_file(void)
+const BIO_METHOD *BIO_s_file(void)
 {
-    return (&methods_filep);
+    return &methods_filep;
 }
 
 static int file_new(BIO *bi)
@@ -208,13 +116,13 @@ static int file_new(BIO *bi)
     bi->num = 0;
     bi->ptr = NULL;
     bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */
-    return (1);
+    return 1;
 }
 
 static int file_free(BIO *a)
 {
     if (a == NULL)
-        return (0);
+        return 0;
     if (a->shutdown) {
         if ((a->init) && (a->ptr != NULL)) {
             if (a->flags & BIO_FLAGS_UPLINK)
@@ -226,7 +134,7 @@ static int file_free(BIO *a)
         }
         a->init = 0;
     }
-    return (1);
+    return 1;
 }
 
 static int file_read(BIO *b, char *out, int outl)
@@ -240,13 +148,13 @@ static int file_read(BIO *b, char *out, int outl)
             ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
         if (ret == 0
             && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
-            ferror((FILE *)b->ptr)) {
+                                               ferror((FILE *)b->ptr)) {
             SYSerr(SYS_F_FREAD, get_last_sys_error());
             BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
             ret = -1;
         }
     }
-    return (ret);
+    return ret;
 }
 
 static int file_write(BIO *b, const char *in, int inl)
@@ -262,12 +170,12 @@ static int file_write(BIO *b, const char *in, int inl)
             ret = inl;
         /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
         /*
-         * according to Tim Hudson <tjh@cryptsoft.com>, the commented out
+         * according to Tim Hudson <tjh@openssl.org>, the commented out
          * version above can cause 'inl' write calls under some stupid stdio
          * implementations (VMS)
          */
     }
-    return (ret);
+    return ret;
 }
 
 static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
@@ -276,6 +184,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
     FILE *fp = (FILE *)b->ptr;
     FILE **fpp;
     char p[4];
+    int st;
 
     switch (cmd) {
     case BIO_C_FILE_SEEK:
@@ -307,8 +216,11 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
 #   if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
 #    define _IOB_ENTRIES 20
 #   endif
-#   if defined(_IOB_ENTRIES)
         /* Safety net to catch purely internal BIO_set_fp calls */
+#   if defined(_MSC_VER) && _MSC_VER>=1900
+        if (ptr == stdin || ptr == stdout || ptr == stderr)
+            BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+#   elif defined(_IOB_ENTRIES)
         if ((size_t)ptr >= (size_t)stdin &&
             (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
             BIO_clear_flags(b, BIO_FLAGS_UPLINK);
@@ -326,13 +238,6 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
                 _setmode(fd, _O_TEXT);
             else
                 _setmode(fd, _O_BINARY);
-#  elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
-            int fd = fileno((FILE *)ptr);
-            /* Under CLib there are differences in file modes */
-            if (num & BIO_FP_TEXT)
-                setmode(fd, O_TEXT);
-            else
-                setmode(fd, O_BINARY);
 #  elif defined(OPENSSL_SYS_MSDOS)
             int fd = fileno((FILE *)ptr);
             /* Set correct text/binary mode */
@@ -346,7 +251,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
                 } else
                     _setmode(fd, _O_BINARY);
             }
-#  elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+#  elif defined(OPENSSL_SYS_WIN32_CYGWIN)
             int fd = fileno((FILE *)ptr);
             if (num & BIO_FP_TEXT)
                 setmode(fd, O_TEXT);
@@ -360,33 +265,27 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
         b->shutdown = (int)num & BIO_CLOSE;
         if (num & BIO_FP_APPEND) {
             if (num & BIO_FP_READ)
-                BUF_strlcpy(p, "a+", sizeof p);
+                OPENSSL_strlcpy(p, "a+", sizeof(p));
             else
-                BUF_strlcpy(p, "a", sizeof p);
+                OPENSSL_strlcpy(p, "a", sizeof(p));
         } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
-            BUF_strlcpy(p, "r+", sizeof p);
+            OPENSSL_strlcpy(p, "r+", sizeof(p));
         else if (num & BIO_FP_WRITE)
-            BUF_strlcpy(p, "w", sizeof p);
+            OPENSSL_strlcpy(p, "w", sizeof(p));
         else if (num & BIO_FP_READ)
-            BUF_strlcpy(p, "r", sizeof p);
+            OPENSSL_strlcpy(p, "r", sizeof(p));
         else {
             BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
             ret = 0;
             break;
         }
-#  if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+#  if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32_CYGWIN)
         if (!(num & BIO_FP_TEXT))
-            strcat(p, "b");
+            OPENSSL_strlcat(p, "b", sizeof(p));
         else
-            strcat(p, "t");
+            OPENSSL_strlcat(p, "t", sizeof(p));
 #  endif
-#  if defined(OPENSSL_SYS_NETWARE)
-        if (!(num & BIO_FP_TEXT))
-            strcat(p, "b");
-        else
-            strcat(p, "t");
-#  endif
-        fp = fopen(ptr, p);
+        fp = openssl_fopen(ptr, p);
         if (fp == NULL) {
             SYSerr(SYS_F_FOPEN, get_last_sys_error());
             ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
@@ -413,10 +312,14 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
         b->shutdown = (int)num;
         break;
     case BIO_CTRL_FLUSH:
-        if (b->flags & BIO_FLAGS_UPLINK)
-            UP_fflush(b->ptr);
-        else
-            fflush((FILE *)b->ptr);
+        st = b->flags & BIO_FLAGS_UPLINK
+                ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr);
+        if (st == EOF) {
+            SYSerr(SYS_F_FFLUSH, get_last_sys_error());
+            ERR_add_error_data(1, "fflush()");
+            BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+            ret = 0;
+        }
         break;
     case BIO_CTRL_DUP:
         ret = 1;
@@ -430,7 +333,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
         ret = 0;
         break;
     }
-    return (ret);
+    return ret;
 }
 
 static int file_gets(BIO *bp, char *buf, int size)
@@ -448,7 +351,7 @@ static int file_gets(BIO *bp, char *buf, int size)
     if (buf[0] != '\0')
         ret = strlen(buf);
  err:
-    return (ret);
+    return ret;
 }
 
 static int file_puts(BIO *bp, const char *str)
@@ -457,7 +360,65 @@ static int file_puts(BIO *bp, const char *str)
 
     n = strlen(str);
     ret = file_write(bp, str, n);
-    return (ret);
+    return ret;
+}
+
+#else
+
+static int file_write(BIO *b, const char *in, int inl)
+{
+    return -1;
+}
+static int file_read(BIO *b, char *out, int outl)
+{
+    return -1;
+}
+static int file_puts(BIO *bp, const char *str)
+{
+    return -1;
+}
+static int file_gets(BIO *bp, char *buf, int size)
+{
+    return 0;
+}
+static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    return 0;
+}
+static int file_new(BIO *bi)
+{
+    return 0;
+}
+static int file_free(BIO *a)
+{
+    return 0;
+}
+
+static const BIO_METHOD methods_filep = {
+    BIO_TYPE_FILE,
+    "FILE pointer",
+    /* TODO: Convert to new style write function */
+    bwrite_conv,
+    file_write,
+    /* TODO: Convert to new style read function */
+    bread_conv,
+    file_read,
+    file_puts,
+    file_gets,
+    file_ctrl,
+    file_new,
+    file_free,
+    NULL,                      /* file_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_file(void)
+{
+    return &methods_filep;
+}
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+{
+    return NULL;
 }
 
 # endif                         /* OPENSSL_NO_STDIO */