Skip to content

Commit 280d4c2

Browse files
davidbenjustsmth
authored andcommitted
Consistently open files in binary mode on Windows
BIO_*_filename, in upstream OpenSSL, opens in binary mode on Windows, not text mode. We seem to have lost those ifdefs in the fork. But since C mandates the 'b' suffix (POSIX just ignores it), apply it consistently to all OSes for simplicity. This fixes X509_FILETYPE_ASN1 in X509_STORE's file-based machinery on Windows. Also fix the various BIO_new_file calls to all specify binary mode. Looking through them, I don't think any of them care (they're all parsing PEM), but let's just apply it across the board so we don't have to think about this. Update-Note: BIO_read_filename, etc., now open in binary mode on Windows. This matches OpenSSL behavior. Change-Id: I7e555085d5c66ad2f205b476d0317570075bbadb Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/66009 Commit-Queue: David Benjamin <[email protected]> Reviewed-by: Bob Beck <[email protected]> (cherry picked from commit cadebfd6398e017addaae4878662aadb42f60bda)
1 parent 49cccd7 commit 280d4c2

File tree

5 files changed

+43
-15
lines changed

5 files changed

+43
-15
lines changed

crypto/bio/bio_test.cc

+27-3
Original file line numberDiff line numberDiff line change
@@ -749,19 +749,25 @@ TEST(BIOTest, Gets) {
749749
SCOPED_TRACE("file");
750750

751751
// Test |BIO_new_file|.
752-
bssl::UniquePtr<BIO> bio(BIO_new_file(file.path().c_str(), "r"));
752+
bssl::UniquePtr<BIO> bio(BIO_new_file(file.path().c_str(), "rb"));
753753
ASSERT_TRUE(bio);
754754
check_bio_gets(bio.get());
755755

756+
// Test |BIO_read_filename|.
757+
bio.reset(BIO_new(BIO_s_file()));
758+
ASSERT_TRUE(bio);
759+
ASSERT_TRUE(BIO_read_filename(bio.get(), file.path().c_str()));
760+
check_bio_gets(bio.get());
761+
756762
// Test |BIO_NOCLOSE|.
757-
ScopedFILE file_obj = file.Open("r");
763+
ScopedFILE file_obj = file.Open("rb");
758764
ASSERT_TRUE(file_obj);
759765
bio.reset(BIO_new_fp(file_obj.get(), BIO_NOCLOSE));
760766
ASSERT_TRUE(bio);
761767
check_bio_gets(bio.get());
762768

763769
// Test |BIO_CLOSE|.
764-
file_obj = file.Open("r");
770+
file_obj = file.Open("rb");
765771
ASSERT_TRUE(file_obj);
766772
bio.reset(BIO_new_fp(file_obj.get(), BIO_CLOSE));
767773
ASSERT_TRUE(bio);
@@ -825,6 +831,24 @@ TEST(BIOTest, ExternalData) {
825831
EXPECT_EQ(retrieved_data->custom_data, 123);
826832
}
827833

834+
// Test that, on Windows, |BIO_read_filename| opens files in binary mode.
835+
TEST(BIOTest, BinaryMode) {
836+
if (SkipTempFileTests()) {
837+
GTEST_SKIP();
838+
}
839+
840+
TemporaryFile file;
841+
ASSERT_TRUE(file.Init("\r\n"));
842+
843+
// Reading from the file should give back the exact bytes we put in.
844+
bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
845+
ASSERT_TRUE(bio);
846+
ASSERT_TRUE(BIO_read_filename(bio.get(), file.path().c_str()));
847+
char buf[2];
848+
ASSERT_EQ(2, BIO_read(bio.get(), buf, 2));
849+
EXPECT_EQ(Bytes(buf, 2), Bytes("\r\n"));
850+
}
851+
828852
// Run through the tests twice, swapping |bio1| and |bio2|, for symmetry.
829853
class BIOPairTest : public testing::TestWithParam<bool> {};
830854

crypto/bio/file.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,16 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
218218
const char *mode;
219219
if (num & BIO_FP_APPEND) {
220220
if (num & BIO_FP_READ) {
221-
mode = "a+";
221+
mode = "ab+";
222222
} else {
223-
mode = "a";
223+
mode = "ab";
224224
}
225225
} else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) {
226-
mode = "r+";
226+
mode = "rb+";
227227
} else if (num & BIO_FP_WRITE) {
228-
mode = "w";
228+
mode = "wb";
229229
} else if (num & BIO_FP_READ) {
230-
mode = "r";
230+
mode = "rb";
231231
} else {
232232
OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
233233
ret = 0;

crypto/x509/by_file.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) {
228228
if (type != X509_FILETYPE_PEM) {
229229
return X509_load_cert_file(ctx, file, type);
230230
}
231-
in = BIO_new_file(file, "r");
231+
in = BIO_new_file(file, "rb");
232232
if (!in) {
233233
OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
234234
return 0;

include/openssl/bio.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -567,22 +567,26 @@ OPENSSL_EXPORT int BIO_set_fp(BIO *bio, FILE *file, int close_flag);
567567

568568
// BIO_read_filename opens |filename| for reading and sets the result as the
569569
// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE|
570-
// will be closed when |bio| is freed.
570+
// will be closed when |bio| is freed. On Windows, the file is opened in binary
571+
// mode.
571572
OPENSSL_EXPORT int BIO_read_filename(BIO *bio, const char *filename);
572573

573574
// BIO_write_filename opens |filename| for writing and sets the result as the
574575
// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE|
575-
// will be closed when |bio| is freed.
576+
// will be closed when |bio| is freed. On Windows, the file is opened in binary
577+
// mode.
576578
OPENSSL_EXPORT int BIO_write_filename(BIO *bio, const char *filename);
577579

578580
// BIO_append_filename opens |filename| for appending and sets the result as
579581
// the |FILE| for |bio|. It returns one on success and zero otherwise. The
580-
// |FILE| will be closed when |bio| is freed.
582+
// |FILE| will be closed when |bio| is freed. On Windows, the file is opened in
583+
// binary mode.
581584
OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename);
582585

583586
// BIO_rw_filename opens |filename| for reading and writing and sets the result
584587
// as the |FILE| for |bio|. It returns one on success and zero otherwise. The
585-
// |FILE| will be closed when |bio| is freed.
588+
// |FILE| will be closed when |bio| is freed. On Windows, the file is opened in
589+
// binary mode.
586590
OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename);
587591

588592
// BIO_tell returns the file offset of |bio|, or a negative number on error or

ssl/ssl_file.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ int SSL_add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio) {
204204
}
205205

206206
STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
207-
bssl::UniquePtr<BIO> in(BIO_new_file(file, "r"));
207+
bssl::UniquePtr<BIO> in(BIO_new_file(file, "rb"));
208208
if (in == nullptr) {
209209
return nullptr;
210210
}
@@ -219,7 +219,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
219219

220220
int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
221221
const char *file) {
222-
bssl::UniquePtr<BIO> in(BIO_new_file(file, "r"));
222+
bssl::UniquePtr<BIO> in(BIO_new_file(file, "rb"));
223223
if (in == nullptr) {
224224
return 0;
225225
}

0 commit comments

Comments
 (0)