zoukankan      html  css  js  c++  java
  • 转一篇OpenSSL的例子:简单的TLS服务器

    原名:Simple TLS Server

    原址:https://wiki.openssl.org/index.php/Simple_TLS_Server

    Windows下就不要从源码编译OpenSSL了,麻烦。下载一些库与头文件进行链接编译吧。

    Windows虽然有OpenSSL的功能,但是没有好的并且简单的例子演示如何实现TLS服务器。

    原文:

    The code below is a complete implementation of a minimal TLS server. The first thing we do is initialise openssl in the init_openssl() function by loading the strings used for error messages, and setting up the algorithms needed for TLS. We then create an SSL_CTX or SSL context. This is created using the SSLv23_server_method which despite its name actually creates a server that will negotiate the highest version of SSL/TLS supported by the client it is connecting to. The context is then configured - we use SSL_CTX_set_ecdh_auto to tell openssl to handle selecting the right elliptic curves for us (this function isn't available in older versions of openssl which required this to be done manually). The final step of configuring the context is to specify the certificate and private key to use.

    Next we perform some normal socket programming and create a new server socket, there's nothing openssl specific about this code. Whenever we get a new connection we call accept as normal. To handle the TLS we create a new SSL structure, this holds the information related to this particular connection. We use SSL_set_fd to tell openssl the file descriptor to use for the communication. In this example, we call SSL_accept to handle the server side of the TLS handshake, then use SSL_write() to send our message. Finally we clean up the various structures.

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <openssl/ssl.h>
    #include <openssl/err.h>
    
    int create_socket(int port)
    {
        int s;
        struct sockaddr_in addr;
    
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
        s = socket(AF_INET, SOCK_STREAM, 0);
        if (s < 0) {
        perror("Unable to create socket");
        exit(EXIT_FAILURE);
        }
    
        if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("Unable to bind");
        exit(EXIT_FAILURE);
        }
    
        if (listen(s, 1) < 0) {
        perror("Unable to listen");
        exit(EXIT_FAILURE);
        }
    
        return s;
    }
    
    void init_openssl()
    { 
        SSL_load_error_strings();    
        OpenSSL_add_ssl_algorithms();
    }
    
    void cleanup_openssl()
    {
        EVP_cleanup();
    }
    
    SSL_CTX *create_context()
    {
        const SSL_METHOD *method;
        SSL_CTX *ctx;
    
        method = SSLv23_server_method();
    
        ctx = SSL_CTX_new(method);
        if (!ctx) {
        perror("Unable to create SSL context");
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
        }
    
        return ctx;
    }
    
    void configure_context(SSL_CTX *ctx)
    {
        SSL_CTX_set_ecdh_auto(ctx, 1);
    
        /* Set the key and cert */
        if (SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM) <= 0) {
            ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
        }
    
        if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) <= 0 ) {
            ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
        }
    }
    
    int main(int argc, char **argv)
    {
        int sock;
        SSL_CTX *ctx;
    
        init_openssl();
        ctx = create_context();
    
        configure_context(ctx);
    
        sock = create_socket(4433);
    
        /* Handle connections */
        while(1) {
            struct sockaddr_in addr;
            uint len = sizeof(addr);
            SSL *ssl;
            const char reply[] = "test
    ";
    
            int client = accept(sock, (struct sockaddr*)&addr, &len);
            if (client < 0) {
                perror("Unable to accept");
                exit(EXIT_FAILURE);
            }
    
            ssl = SSL_new(ctx);
            SSL_set_fd(ssl, client);
    
            if (SSL_accept(ssl) <= 0) {
                ERR_print_errors_fp(stderr);
            }
            else {
                SSL_write(ssl, reply, strlen(reply));
            }
    
            SSL_free(ssl);
            close(client);
        }
    
        close(sock);
        SSL_CTX_free(ctx);
        cleanup_openssl();
    }
  • 相关阅读:
    django-缓存的应用
    Faster-RCNN用于场景文字检测训练测试过程记录(转)
    faster-rcnn在ubuntu16.04环境下的超级详细的配置(转)
    Effective C++读书笔记(转)
    c++中的static,const,const static以及它们的初始化
    [leetcode]Validate Binary Search Tree 验证二叉搜索树
    二叉树的遍历方式(迭代)
    c++中string与int之间的相互转换
    c++中 cin,cin.get(),cin.getline(),getline()用法说明
    N皇后问题代码
  • 原文地址:https://www.cnblogs.com/fyter/p/simple_tls_server.html
Copyright © 2011-2022 走看看