summaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'server.c')
-rw-r--r--server.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/server.c b/server.c
new file mode 100644
index 0000000..da25676
--- /dev/null
+++ b/server.c
@@ -0,0 +1,144 @@
+
+#include <netdb.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#include <openssl/rsa.h>
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+#include "common.h"
+
+
+int main(void)
+{
+ const SSL_METHOD *meth;
+ SSL_CTX *ctx;
+ char cwd[256];
+ char *set;
+ int ret;
+ int listen_sd;
+ struct sockaddr_in sa_serv;
+ struct sockaddr_in sa_cli;
+ int sd;
+ SSL *ssl;
+ X509 *client_cert;
+ char *str;
+ char buf[64];
+
+ /* Crypto */
+
+ SSL_load_error_strings();
+ OpenSSL_add_ssl_algorithms();
+
+ meth = TLSv1_2_server_method();
+ ctx = SSL_CTX_new(meth);
+ CHK_NULL(ctx);
+
+ set = getcwd(cwd, sizeof(cwd));
+ CHK_NULL(set);
+
+ ret = SSL_CTX_load_verify_locations(ctx, "cacert.pem", cwd);
+ CHK_SSL(ret);
+
+ /*
+ ret = SSL_CTX_set_default_verify_paths(ctx);
+ CHK_SSL(ret);
+ */
+
+ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file("cacert.pem"));
+
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
+
+ ret = SSL_CTX_use_certificate_chain_file(ctx, "servercert.pem");
+ CHK_SSL(ret);
+
+ ret = SSL_CTX_use_PrivateKey_file(ctx, "serverkey.pem", SSL_FILETYPE_PEM);
+ CHK_SSL(ret);
+
+ ret = SSL_CTX_check_private_key(ctx);
+ CHK_SSL(ret);
+
+ /* Networking */
+
+ listen_sd = socket(AF_INET, SOCK_STREAM, 0);
+ CHK_ERR(listen_sd, "socket");
+
+ memset(&sa_serv, 0, sizeof(sa_serv));
+
+ sa_serv.sin_family = AF_INET;
+ sa_serv.sin_addr.s_addr = INADDR_ANY;
+ sa_serv.sin_port = htons(1111);
+
+ ret = bind(listen_sd, (struct sockaddr *)&sa_serv, sizeof(sa_serv));
+ CHK_ERR(ret, "bind");
+
+ /* Waiting */
+
+ ret = listen(listen_sd, 5);
+ CHK_ERR(ret, "listen");
+
+ sd = accept(listen_sd, (struct sockaddr *)&sa_cli, (socklen_t []) { sizeof(sa_cli) });
+ CHK_ERR(sd, "accept");
+
+ close(listen_sd);
+
+ printf("Connection from %lx, port %hu\n", (unsigned long)sa_cli.sin_addr.s_addr, sa_cli.sin_port);
+
+ /* Server side SSL */
+
+ ssl = SSL_new(ctx);
+ CHK_NULL(ssl);
+
+ SSL_set_fd(ssl, sd);
+
+ ret = SSL_accept(ssl);
+ CHK_SSL(ret);
+
+ /* Info */
+
+ printf("SSL connection using %s\n", SSL_get_cipher(ssl));
+
+ client_cert = SSL_get_peer_certificate(ssl);
+ CHK_NULL(client_cert);
+
+ printf("Client certificate:\n");
+
+ str = X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0);
+ CHK_NULL(str);
+ printf("\tsubject: %s\n", str);
+ OPENSSL_free(str);
+
+ str = X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0);
+ CHK_NULL(str);
+ printf("\tissuer: %s\n", str);
+ OPENSSL_free(str);
+
+ X509_free(client_cert);
+
+ /* Exchange */
+
+ ret = SSL_write(ssl, "Hello Client!", strlen("Hello Client!"));
+ CHK_SSL_WRAPPER(ret);
+
+ ret = SSL_read(ssl, buf, sizeof(buf) - 1);
+ CHK_SSL_WRAPPER(ret);
+
+ buf[ret] = '\0';
+
+ printf("Got %d chars: '%s'\n", ret, buf);
+
+ /* End */
+
+ SSL_shutdown(ssl);
+ close(sd);
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+
+ return EXIT_SUCCESS;
+
+}