zoukankan      html  css  js  c++  java
  • 如何做一个用于测试SSL版本的客户端

    最近由于工作的需要,需要升级建链过程中SSL的版本,因此有了这篇博文。

    科普:

      版本排序,从小到大:SSLv2, SSLv3, TLSv1, TLSv1.1 and TLSv1.2

    SSL_CTX_new:creates a new SSL_CTX object as framework to establish TLS/SSL enabled connections.
     #include <openssl/ssl.h>
    
     SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);

    其中,要想知道 SSL_METHOD有多少个可以用的方法,参见:http://openssl.cs.utah.edu/docs/ssl/SSL_CTX_new.html

    SSL_CTX_set_options() or SSL_set_options():该方法是用来禁止使用什么协议来建链的。其中有以下选项可以填写:

    SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1 and SSL_OP_NO_TLSv1_2

    通过字面意思,我们可以知道其用法。

    Demo

      1 #include <sys/socket.h>
      2 #include <resolv.h>
      3 #include <netdb.h>
      4 #include <netinet/in.h>
      5 #include <arpa/inet.h>
      6 #include <string.h>
      7 
      8 #include <openssl/bio.h>
      9 #include <openssl/ssl.h>
     10 #include <openssl/err.h>
     11 #include <openssl/pem.h>
     12 #include <openssl/x509.h>
     13 #include <openssl/x509_vfy.h>
     14 
     15 int create_socket(char[], BIO *);
     16 
     17 int main() {
     18 
     19     char dest_url[] = "https://www.baidu.com";
     20     BIO *certbio = NULL;
     21     BIO *outbio = NULL;
     22     X509 *cert = NULL;
     23     X509_NAME *certname = NULL;
     24     const SSL_METHOD *method;
     25     SSL_CTX *ctx;
     26     SSL *ssl;
     27     int server = 0;
     28     int ret, i;
     29 
     30     /* ---------------------------------------------------------- *
     31      * 初始化OpenSSL                                                *
     32      * ---------------------------------------------------------- */
     33     OpenSSL_add_all_algorithms();
     34     ERR_load_BIO_strings();
     35     ERR_load_crypto_strings();
     36     SSL_load_error_strings();
     37 
     38     /* ---------------------------------------------------------- *
     39      * 创建一个BIO的输入和输出.                                   *
     40      * ---------------------------------------------------------- */
     41     certbio = BIO_new(BIO_s_file());
     42     outbio = BIO_new_fp(stdout, BIO_NOCLOSE);
     43 
     44     /* ---------------------------------------------------------- *
     45      * 初始化SSL库和注册算法                                      *
     46      * ---------------------------------------------------------- */
     47     if (SSL_library_init() < 0)
     48         BIO_printf(outbio, "Could not initialize the OpenSSL library !
    ");
     49 
     50     /* ---------------------------------------------------------- *
     51      * 发送SSL2 SSL3 TLS 1.0 TLS 2.0 TLS 3.0 与服务器建链         *
     52      * ---------------------------------------------------------- */
     53     method = SSLv23_client_method();
     54 
     55     /* ---------------------------------------------------------- *
     56      * 创建一个新的SSL上下文                                      *
     57      * ---------------------------------------------------------- */
     58     if ((ctx = SSL_CTX_new(method)) == NULL)
     59         BIO_printf(outbio, "Unable to create a new SSL context structure.
    ");
     60 
     61     /* ---------------------------------------------------------- *
     62      * 禁止使用SSLv3建链                                          *
     63      * ---------------------------------------------------------- */
     64     SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
     65 
     66     /* ---------------------------------------------------------- *
     67      * 创建一个新的SSL的状态                                      *
     68      * ---------------------------------------------------------- */
     69     ssl = SSL_new(ctx);
     70 
     71     /* ---------------------------------------------------------- *
     72      * 创建一个优先的SSL TCP 链接                                 *
     73      * ---------------------------------------------------------- */
     74     server = create_socket(dest_url, outbio);
     75     if (server != 0)
     76         BIO_printf(outbio, "Successfully made the TCP connection to: %s.
    ",
     77                 dest_url);
     78 
     79     /* ---------------------------------------------------------- *
     80      * 关联socket的会话                                           *
     81      * ---------------------------------------------------------- */
     82     SSL_set_fd(ssl, server);
     83 
     84     /* ---------------------------------------------------------- *
     85      * 建立SSL 链接,返回1成功                                    *
     86      * ---------------------------------------------------------- */
     87     if (SSL_connect(ssl) != 1)
     88         BIO_printf(outbio, "Error: Could not build a SSL session to: %s.
    ",
     89                 dest_url);
     90     else
     91         BIO_printf(outbio, "Successfully enabled SSL/TLS session to: %s.
    ",
     92                 dest_url);
     93 
     94     /* ---------------------------------------------------------- *
     95      * 得到服务端的证书到X509结构体                               *
     96      * ---------------------------------------------------------- */
     97     cert = SSL_get_peer_certificate(ssl);
     98     if (cert == NULL)
     99         BIO_printf(outbio, "Error: Could not get a certificate from: %s.
    ",
    100                 dest_url);
    101     else
    102         BIO_printf(outbio, "Retrieved the server's certificate from: %s.
    ",
    103                 dest_url);
    104 
    105     /* ---------------------------------------------------------- *
    106      * 提取各种证书信息                    *
    107      * -----------------------------------------------------------*/
    108     certname = X509_NAME_new();
    109     certname = X509_get_subject_name(cert);
    110 
    111     /* ---------------------------------------------------------- *
    112      * 这里显示证书的主题                                         *
    113      * -----------------------------------------------------------*/
    114     BIO_printf(outbio, "Displaying the certificate subject data:
    ");
    115     X509_NAME_print_ex(outbio, certname, 0, 0);
    116     BIO_printf(outbio, "
    ");
    117 
    118     /* ---------------------------------------------------------- *
    119      * 释放不再使用的结构体                  *
    120      * -----------------------------------------------------------*/
    121     SSL_free(ssl);
    122     close(server);
    123     X509_free(cert);
    124     SSL_CTX_free(ctx);
    125     BIO_printf(outbio, "Finished SSL/TLS connection with server: %s.
    ",
    126             dest_url);
    127     return (0);
    128 }
    129 
    130 /* ---------------------------------------------------------- *
    131  * create_socket() 和服务端建立TCP的socket链接                *
    132  * ---------------------------------------------------------- */
    133 int create_socket(char url_str[], BIO *out) {
    134     int sockfd;
    135     char hostname[256] = "";
    136     char portnum[6] = "443";
    137     char proto[6] = "";
    138     char *tmp_ptr = NULL;
    139     int port;
    140     struct hostent *host;
    141     struct sockaddr_in dest_addr;
    142 
    143     /* ---------------------------------------------------------- *
    144      * 移除url_str的末尾 /                                        *
    145      * ---------------------------------------------------------- */
    146     if (url_str[strlen(url_str)] == '/')
    147         url_str[strlen(url_str)] = '';
    148 
    149     /* ---------------------------------------------------------- *
    150      * the first : ends the protocol string, i.e. http            *
    151      * ---------------------------------------------------------- */
    152     strncpy(proto, url_str, (strchr(url_str, ':') - url_str));
    153 
    154     /* ---------------------------------------------------------- *
    155      * the hostname starts after the "://" part                   *
    156      * ---------------------------------------------------------- */
    157     strncpy(hostname, strstr(url_str, "://") + 3, sizeof(hostname));
    158 
    159     /* ---------------------------------------------------------- *
    160      * if the hostname contains a colon :, we got a port number   *
    161      * ---------------------------------------------------------- */
    162     if (strchr(hostname, ':')) {
    163         tmp_ptr = strchr(hostname, ':');
    164         /* the last : starts the port number, if avail, i.e. 8443 */
    165         strncpy(portnum, tmp_ptr + 1, sizeof(portnum));
    166         *tmp_ptr = '';
    167     }
    168 
    169     port = atoi(portnum);
    170 
    171     if ((host = gethostbyname(hostname)) == NULL) {
    172         BIO_printf(out, "Error: Cannot resolve hostname %s.
    ", hostname);
    173         abort();
    174     }
    175 
    176     /* ---------------------------------------------------------- *
    177      * create the basic TCP socket                                *
    178      * ---------------------------------------------------------- */
    179     sockfd = socket(AF_INET, SOCK_STREAM, 0);
    180 
    181     dest_addr.sin_family = AF_INET;
    182     dest_addr.sin_port = htons(port);
    183     dest_addr.sin_addr.s_addr = *(long*) (host->h_addr);
    184 
    185     /* ---------------------------------------------------------- *
    186      * Zeroing the rest of the struct                             *
    187      * ---------------------------------------------------------- */
    188     memset(&(dest_addr.sin_zero), '', 8);
    189 
    190     tmp_ptr = inet_ntoa(dest_addr.sin_addr);
    191 
    192     /* ---------------------------------------------------------- *
    193      * Try to make the host connect here                          *
    194      * ---------------------------------------------------------- */
    195     if (connect(sockfd, (struct sockaddr *) &dest_addr, sizeof(struct sockaddr))
    196             == -1) {
    197         BIO_printf(out, "Error: Cannot connect to host %s [%s] on port %d.
    ",
    198                 hostname, tmp_ptr, port);
    199     }
    200 
    201     return sockfd;
    202 }
    View Code
  • 相关阅读:
    ansible自动化运维04
    ansible自动化运维03
    ansible自动化运维02
    ansible自动化运维01
    mysql innodb存储引擎和一些参数优化
    Mysql 数据库常用配置命令
    zabbix server3.4 使用mailx配置邮件报警
    32_redis cluster的核心原理分析:gossip通信、jedis smart定位、主备切换
    31_redis cluster的自动化slave迁移实现更强的高可用架构的部署方案
    30_redis cluster通过master水平扩容来支撑更高的读写吞吐+海量数据
  • 原文地址:https://www.cnblogs.com/sxmcACM/p/6082907.html
Copyright © 2011-2022 走看看