diff options
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/bio/bss_file.c')
-rw-r--r-- | Cryptlib/OpenSSL/crypto/bio/bss_file.c | 251 |
1 files changed, 154 insertions, 97 deletions
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_file.c b/Cryptlib/OpenSSL/crypto/bio/bss_file.c index 6af2d9cb..a6e3b3ac 100644 --- a/Cryptlib/OpenSSL/crypto/bio/bss_file.c +++ b/Cryptlib/OpenSSL/crypto/bio/bss_file.c @@ -1,10 +1,59 @@ -/* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. +/* 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. * - * 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 + * 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. + * + * 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.] */ /*- @@ -36,19 +85,24 @@ # 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); -static int file_read(BIO *h, char *buf, int size); -static int file_puts(BIO *h, const char *str); -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 const BIO_METHOD methods_filep = { +static int MS_CALLBACK file_write(BIO *h, const char *buf, int num); +static int MS_CALLBACK file_read(BIO *h, char *buf, int size); +static int MS_CALLBACK file_puts(BIO *h, const char *str); +static int MS_CALLBACK file_gets(BIO *h, char *str, int size); +static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int MS_CALLBACK file_new(BIO *h); +static int MS_CALLBACK file_free(BIO *data); +static BIO_METHOD methods_filep = { BIO_TYPE_FILE, "FILE pointer", file_write, @@ -61,14 +115,61 @@ static const BIO_METHOD methods_filep = { NULL, }; +static FILE *file_fopen(const char *filename, const char *mode) +{ + 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, sizeof(wmode) / sizeof(wmode[0])) && + (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 + return (file); +} + BIO *BIO_new_file(const char *filename, const char *mode) { BIO *ret; - FILE *file = openssl_fopen(filename, mode); - int fp_flags = BIO_CLOSE; - - if (strchr(mode, 'b') == NULL) - fp_flags |= BIO_FP_TEXT; + FILE *file = file_fopen(filename, mode); if (file == NULL) { SYSerr(SYS_F_FOPEN, get_last_sys_error()); @@ -90,7 +191,7 @@ BIO *BIO_new_file(const char *filename, const char *mode) BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage * UPLINK */ - BIO_set_fp(ret, file, fp_flags); + BIO_set_fp(ret, file, BIO_CLOSE); return (ret); } @@ -101,18 +202,18 @@ BIO *BIO_new_fp(FILE *stream, int close_flag) if ((ret = BIO_new(BIO_s_file())) == NULL) return (NULL); - /* redundant flag, left for documentation purposes */ - BIO_set_flags(ret, BIO_FLAGS_UPLINK); + BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for + * documentation puposes */ BIO_set_fp(ret, stream, close_flag); return (ret); } -const BIO_METHOD *BIO_s_file(void) +BIO_METHOD *BIO_s_file(void) { return (&methods_filep); } -static int file_new(BIO *bi) +static int MS_CALLBACK file_new(BIO *bi) { bi->init = 0; bi->num = 0; @@ -121,7 +222,7 @@ static int file_new(BIO *bi) return (1); } -static int file_free(BIO *a) +static int MS_CALLBACK file_free(BIO *a) { if (a == NULL) return (0); @@ -139,7 +240,7 @@ static int file_free(BIO *a) return (1); } -static int file_read(BIO *b, char *out, int outl) +static int MS_CALLBACK file_read(BIO *b, char *out, int outl) { int ret = 0; @@ -150,7 +251,7 @@ 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; @@ -159,7 +260,7 @@ static int file_read(BIO *b, char *out, int outl) return (ret); } -static int file_write(BIO *b, const char *in, int inl) +static int MS_CALLBACK file_write(BIO *b, const char *in, int inl) { int ret = 0; @@ -180,7 +281,7 @@ static int file_write(BIO *b, const char *in, int inl) return (ret); } -static long file_ctrl(BIO *b, int cmd, long num, void *ptr) +static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 1; FILE *fp = (FILE *)b->ptr; @@ -217,11 +318,8 @@ 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); @@ -239,6 +337,13 @@ 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 */ @@ -252,7 +357,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) } else _setmode(fd, _O_BINARY); } -# elif defined(OPENSSL_SYS_WIN32_CYGWIN) +# elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) int fd = fileno((FILE *)ptr); if (num & BIO_FP_TEXT) setmode(fd, O_TEXT); @@ -266,27 +371,33 @@ 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) - OPENSSL_strlcpy(p, "a+", sizeof p); + BUF_strlcpy(p, "a+", sizeof p); else - OPENSSL_strlcpy(p, "a", sizeof p); + BUF_strlcpy(p, "a", sizeof p); } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) - OPENSSL_strlcpy(p, "r+", sizeof p); + BUF_strlcpy(p, "r+", sizeof p); else if (num & BIO_FP_WRITE) - OPENSSL_strlcpy(p, "w", sizeof p); + BUF_strlcpy(p, "w", sizeof p); else if (num & BIO_FP_READ) - OPENSSL_strlcpy(p, "r", sizeof p); + BUF_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_WIN32_CYGWIN) +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) if (!(num & BIO_FP_TEXT)) strcat(p, "b"); else strcat(p, "t"); # endif - fp = openssl_fopen(ptr, p); +# if defined(OPENSSL_SYS_NETWARE) + if (!(num & BIO_FP_TEXT)) + strcat(p, "b"); + else + strcat(p, "t"); +# endif + fp = file_fopen(ptr, p); if (fp == NULL) { SYSerr(SYS_F_FOPEN, get_last_sys_error()); ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); @@ -333,7 +444,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) return (ret); } -static int file_gets(BIO *bp, char *buf, int size) +static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) { int ret = 0; @@ -351,7 +462,7 @@ static int file_gets(BIO *bp, char *buf, int size) return (ret); } -static int file_puts(BIO *bp, const char *str) +static int MS_CALLBACK file_puts(BIO *bp, const char *str) { int n, ret; @@ -360,60 +471,6 @@ static int file_puts(BIO *bp, const char *str) 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", - file_write, - file_read, - file_puts, - file_gets, - file_ctrl, - file_new, - file_free, - NULL, -}; - -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 */ #endif /* HEADER_BSS_FILE_C */ |