1 /* Copyright (c) 2014, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 #include <string> 16 #include <vector> 17 18 #include <openssl/crypto.h> 19 #include <openssl/err.h> 20 #include <openssl/ssl.h> 21 22 #if defined(OPENSSL_WINDOWS) 23 #include <fcntl.h> 24 #include <io.h> 25 #else 26 #include <libgen.h> 27 #endif 28 29 #include "internal.h" 30 31 32 static bool IsFIPS(const std::vector<std::string> &args) { 33 printf("%d\n", FIPS_mode()); 34 return true; 35 } 36 37 typedef bool (*tool_func_t)(const std::vector<std::string> &args); 38 39 struct Tool { 40 const char *name; 41 tool_func_t func; 42 }; 43 44 static const Tool kTools[] = { 45 { "ciphers", Ciphers }, 46 { "client", Client }, 47 { "isfips", IsFIPS }, 48 { "generate-ed25519", GenerateEd25519Key }, 49 { "genrsa", GenerateRSAKey }, 50 { "md5sum", MD5Sum }, 51 { "pkcs12", DoPKCS12 }, 52 { "rand", Rand }, 53 { "s_client", Client }, 54 { "s_server", Server }, 55 { "server", Server }, 56 { "sha1sum", SHA1Sum }, 57 { "sha224sum", SHA224Sum }, 58 { "sha256sum", SHA256Sum }, 59 { "sha384sum", SHA384Sum }, 60 { "sha512sum", SHA512Sum }, 61 { "sign", Sign }, 62 { "speed", Speed }, 63 { "", nullptr }, 64 }; 65 66 static void usage(const char *name) { 67 printf("Usage: %s COMMAND\n", name); 68 printf("\n"); 69 printf("Available commands:\n"); 70 71 for (size_t i = 0;; i++) { 72 const Tool &tool = kTools[i]; 73 if (tool.func == nullptr) { 74 break; 75 } 76 printf(" %s\n", tool.name); 77 } 78 } 79 80 static tool_func_t FindTool(const std::string &name) { 81 for (size_t i = 0;; i++) { 82 const Tool &tool = kTools[i]; 83 if (tool.func == nullptr || name == tool.name) { 84 return tool.func; 85 } 86 } 87 } 88 89 int main(int argc, char **argv) { 90 #if defined(OPENSSL_WINDOWS) 91 // Read and write in binary mode. This makes bssl on Windows consistent with 92 // bssl on other platforms, and also makes it consistent with MSYS's commands 93 // like diff(1) and md5sum(1). This is especially important for the digest 94 // commands. 95 if (_setmode(_fileno(stdin), _O_BINARY) == -1) { 96 perror("_setmode(_fileno(stdin), O_BINARY)"); 97 return 1; 98 } 99 if (_setmode(_fileno(stdout), _O_BINARY) == -1) { 100 perror("_setmode(_fileno(stdout), O_BINARY)"); 101 return 1; 102 } 103 if (_setmode(_fileno(stderr), _O_BINARY) == -1) { 104 perror("_setmode(_fileno(stderr), O_BINARY)"); 105 return 1; 106 } 107 #endif 108 109 CRYPTO_library_init(); 110 111 int starting_arg = 1; 112 tool_func_t tool = nullptr; 113 #if !defined(OPENSSL_WINDOWS) 114 tool = FindTool(basename(argv[0])); 115 #endif 116 if (tool == nullptr) { 117 starting_arg++; 118 if (argc > 1) { 119 tool = FindTool(argv[1]); 120 } 121 } 122 if (tool == nullptr) { 123 usage(argv[0]); 124 return 1; 125 } 126 127 std::vector<std::string> args; 128 for (int i = starting_arg; i < argc; i++) { 129 args.push_back(argv[i]); 130 } 131 132 if (!tool(args)) { 133 ERR_print_errors_fp(stderr); 134 return 1; 135 } 136 137 return 0; 138 } 139