1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (c) 2014, Google Inc. 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Permission to use, copy, modify, and/or distribute this software for any 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * purpose with or without fee is hereby granted, provided that the above 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copyright notice and this permission notice appear in all copies. 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/base.h> 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ssl.h> 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h" 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "transport_common.h" 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const struct argument kArguments[] = { 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley { 26e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley "-accept", kRequiredArgument, 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley "The port of the server to bind on; eg 45102", 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley }, 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley { 30e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley "-cipher", kOptionalArgument, 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley "An OpenSSL-style cipher suite string that configures the offered ciphers", 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley }, 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley { 34e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley "-key", kOptionalArgument, 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley "Private-key file to use (default is server.pem)", 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley }, 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley { 38e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley "", kOptionalArgument, "", 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley }, 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}; 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langleybool Server(const std::vector<std::string> &args) { 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!InitSocketLibrary()) { 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return false; 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley std::map<std::string, std::string> args_map; 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!ParseKeyValueArguments(&args_map, args, kArguments)) { 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PrintUsage(kArguments); 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return false; 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley // Server authentication is required. 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley std::string key_file = "server.pem"; 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (args_map.count("-key") != 0) { 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley key_file = args_map["-key"]; 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (SSL_CTX_use_PrivateKey_file(ctx, key_file.c_str(), SSL_FILETYPE_PEM) <= 0) { 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fprintf(stderr, "Failed to load private key: %s\n", key_file.c_str()); 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return false; 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (SSL_CTX_use_certificate_chain_file(ctx, key_file.c_str()) != 1) { 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fprintf(stderr, "Failed to load cert chain: %s\n", key_file.c_str()); 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return false; 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (args_map.count("-cipher") != 0 && 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !SSL_CTX_set_cipher_list(ctx, args_map["-cipher"].c_str())) { 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fprintf(stderr, "Failed setting cipher list\n"); 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return false; 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int sock = -1; 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!Accept(&sock, args_map["-accept"])) { 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return false; 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO *bio = BIO_new_socket(sock, BIO_CLOSE); 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley SSL *ssl = SSL_new(ctx); 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley SSL_set_bio(ssl, bio, bio); 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret = SSL_accept(ssl); 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret != 1) { 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ssl_err = SSL_get_error(ssl, ret); 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fprintf(stderr, "Error while connecting: %d\n", ssl_err); 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_print_errors_cb(PrintErrorCallback, stderr); 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return false; 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fprintf(stderr, "Connected.\n"); 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PrintConnectionInfo(ssl); 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley bool ok = TransferData(ssl, sock); 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley SSL_free(ssl); 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley SSL_CTX_free(ctx); 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ok; 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 103