Enable bssl (md5sum, sha256sum, etc.) on Windows. We deal with the difference between binary and text modes on Windows by doing all I/O in binary mode (including, in particular, stdin/stdout/stderr) and by treating text mode as equivalent to binary mode (i.e. we use Unix line ending semantics). Change-Id: I76a46d8d02cd7efe1931c8272d8f2c311aef3acb Reviewed-on: https://boringssl-review.googlesource.com/3070 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/BUILDING b/BUILDING index 88c96f4..8438daf 100644 --- a/BUILDING +++ b/BUILDING
@@ -70,9 +70,6 @@ * The bssl client, server, s_client, and s_server commands are not built on Windows. - * The bssl md5sum, sha1sum, sha256sum, etc. commands are not built on - Windows. - * The tests written in Go do not work. [1] http://www.cmake.org/download/
diff --git a/tool/digest.cc b/tool/digest.cc index 224b79c..9c75d2d 100644 --- a/tool/digest.cc +++ b/tool/digest.cc
@@ -14,8 +14,6 @@ #include <openssl/base.h> -#if !defined(OPENSSL_WINDOWS) - #include <memory> #include <string> #include <vector> @@ -26,11 +24,23 @@ #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> + +#if !defined(OPENSSL_WINDOWS) #include <unistd.h> +#if !defined(O_BINARY) +#define O_BINARY 0 +#endif +#else +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <io.h> +#define PATH_MAX MAX_PATH +#define read _read +#endif #include <openssl/digest.h> - struct close_delete { void operator()(int *fd) { close(*fd); @@ -70,13 +80,14 @@ static bool OpenFile(int *out_fd, const std::string &filename) { *out_fd = -1; - int fd = open(filename.c_str(), O_RDONLY); + int fd = open(filename.c_str(), O_RDONLY | O_BINARY); if (fd < 0) { fprintf(stderr, "Failed to open input file '%s': %s\n", filename.c_str(), strerror(errno)); return false; } +#if !defined(OPENSSL_WINDOWS) struct stat st; if (fstat(fd, &st)) { fprintf(stderr, "Failed to stat input file '%s': %s\n", filename.c_str(), @@ -88,6 +99,7 @@ fprintf(stderr, "%s: not a regular file\n", filename.c_str()); goto err; } +#endif *out_fd = fd; return true; @@ -179,6 +191,14 @@ return false; } + // TODO: When given "--binary" or "-b", we should print " *" instead of " " + // between the digest and the filename. + // + // MSYS and Cygwin md5sum default to binary mode by default, whereas other + // platforms' tools default to text mode by default. We default to text mode + // by default and consider text mode equivalent to binary mode (i.e. we + // always use Unix semantics, even on Windows), which means that our default + // output will differ from the MSYS and Cygwin tools' default output. printf("%s %s\n", hex_digest.c_str(), source.is_stdin() ? "-" : source.filename().c_str()); return true; @@ -213,7 +233,7 @@ return false; } - file = fdopen(fd, "r"); + file = fdopen(fd, "rb"); if (!file) { perror("fdopen"); close(fd); @@ -366,7 +386,7 @@ switch (arg[i]) { case 'b': case 't': - // Binary/text mode – irrelevent. + // Binary/text mode – irrelevent, even on Windows. break; case 'c': check_mode = true; @@ -381,7 +401,7 @@ } } } else if (arg == "--binary" || arg == "--text") { - // Binary/text mode – irrelevent. + // Binary/text mode – irrelevent, even on Windows. } else if (arg == "--check") { check_mode = true; } else if (arg == "--quiet") { @@ -455,5 +475,3 @@ bool SHA512Sum(const std::vector<std::string> &args) { return DigestSum(EVP_sha512(), args); } - -#endif /* !OPENSSL_WINDOWS */
diff --git a/tool/tool.cc b/tool/tool.cc index 88b6f24..3b24be5 100644 --- a/tool/tool.cc +++ b/tool/tool.cc
@@ -18,7 +18,10 @@ #include <openssl/err.h> #include <openssl/ssl.h> -#if !defined(OPENSSL_WINDOWS) +#if defined(OPENSSL_WINDOWS) +#include <fcntl.h> +#include <io.h> +#else #include <libgen.h> #endif @@ -26,13 +29,13 @@ #if !defined(OPENSSL_WINDOWS) bool Client(const std::vector<std::string> &args); bool Server(const std::vector<std::string> &args); +#endif bool MD5Sum(const std::vector<std::string> &args); bool SHA1Sum(const std::vector<std::string> &args); bool SHA224Sum(const std::vector<std::string> &args); bool SHA256Sum(const std::vector<std::string> &args); bool SHA384Sum(const std::vector<std::string> &args); bool SHA512Sum(const std::vector<std::string> &args); -#endif bool DoPKCS12(const std::vector<std::string> &args); bool Speed(const std::vector<std::string> &args); @@ -51,13 +54,13 @@ { "s_client", Client }, { "server", Server }, { "s_server", Server }, +#endif { "md5sum", MD5Sum }, { "sha1sum", SHA1Sum }, { "sha224sum", SHA224Sum }, { "sha256sum", SHA256Sum }, { "sha384sum", SHA384Sum }, { "sha512sum", SHA512Sum }, -#endif { "", nullptr }, }; @@ -87,6 +90,25 @@ } int main(int argc, char **argv) { +#if defined(OPENSSL_WINDOWS) + // Read and write in binary mode. This makes bssl on Windows consistent with + // bssl on other platforms, and also makes it consistent with MSYS's commands + // like diff(1) and md5sum(1). This is especially important for the digest + // commands. + if (_setmode(_fileno(stdin), _O_BINARY) == -1) { + perror("_setmode(_fileno(stdin), O_BINARY)"); + return 1; + } + if (_setmode(_fileno(stdout), _O_BINARY) == -1) { + perror("_setmode(_fileno(stdout), O_BINARY)"); + return 1; + } + if (_setmode(_fileno(stderr), _O_BINARY) == -1) { + perror("_setmode(_fileno(stderr), O_BINARY)"); + return 1; + } +#endif + SSL_library_init(); int starting_arg = 1;