openssl3.2 - 官方demo学习 - client-conf.c

文章目录

    • [openssl3.2 - 官方demo学习 - client-conf.c](#openssl3.2 - 官方demo学习 - client-conf.c)
    • 笔记
    • client-conf.c
    • [配置文件格式 - connect.cnf](#配置文件格式 - connect.cnf)
    • 备注
    • END

openssl3.2 - 官方demo学习 - client-conf.c

笔记

client-conf.c

client-arg.c是从命令行参数中得到TLS服务器ip/port.

client-conf.c 从配置文件中读取TLS服务器ip/port, 其他相同.

openSSL附带赠送了好多有用的API(这个例子中, 演示了读取配置文件. 不过读取item时, 用的是遍历), 不仅仅是密码学相关.

官方demo中读取配置文件时, 只比对了第一项, 这是不对的, 如果连接处不在第一行, 逻辑就不对了. 修正了这个实现.

配置文件格式 - connect.cnf

注释行, 行首是'#'

配置项行, 名称 = 值

可以有任意个空行

经过 NCONF_get_section()后, sk_CONF_VALUE_num()时, 得到的就是配置项的条目数量.

例子 connect.cnf 的内容如下

bash 复制代码
# Example configuration file

# Comment out the next line to ignore configuration errors
config_diagnostics = 1

# Connects to the default port of s_server
Connect = localhost:4433

# Disable TLS v1.2 for test.
# Protocol = ALL, -TLSv1.2
# Only support 3 curves
Curves = P-521:P-384:P-256

# Restricted signature algorithms
SignatureAlgorithms = RSA+SHA512:ECDSA+SHA512

如果程序不做密码学任务, 带个openSSL库, 也能做好多其他事情.

c 复制代码
/*! \file client-conf.c */

/*
 * Copyright 2013-2023 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <string.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/conf.h>

#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "libssl.lib")

#include <openssl/applink.c> /*! for OPENSSL_Uplink(00007FF8B7EF0FE8,08): no OPENSSL_Applink */

int main(int argc, char **argv)
{
    BIO *sbio = NULL, *out = NULL;
    int i, len, rv;
    char tmpbuf[1024];
    SSL_CTX *ctx = NULL;
    SSL_CONF_CTX *cctx = NULL;
    SSL *ssl = NULL;
    CONF *conf = NULL;
    STACK_OF(CONF_VALUE) *sect = NULL;
    CONF_VALUE *cnf;
    const char *connect_str = "localhost:4433";
    long errline = -1;
    int ret = EXIT_FAILURE;
    int iCfgItemCnt = 0;

    /*!
    用编译完的OpenSSL3.2单步, 有pdb文件, 可以单步进入已经编译好的实现(.c)
    前提是, 编译好, 进行安装的openSSL源码包别动, 7z后备份一下好些
    */

    conf = NCONF_new(NULL);

    if (NCONF_load(conf, "connect.cnf", &errline) <= 0) {
        if (errline <= 0)
            fprintf(stderr, "Error processing config file\n");
        else
            fprintf(stderr, "Error on line %ld\n", errline);
        goto end;
    }

    sect = NCONF_get_section(conf, "default");

    if (sect == NULL) {
        fprintf(stderr, "Error retrieving default section\n");
        goto end;
    }

    ctx = SSL_CTX_new(TLS_client_method());
    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);

    /*! OpenSSL3.2 API中有对配置文件的读取
        即使不用openSSL3.2做密码学方面的编程, 也有很多附带功能啊
        
        配置文件格式
        # 注释
        xx_config_item_name = yy_config_item_value
    */

    iCfgItemCnt = sk_CONF_VALUE_num(sect);
    for (i = 0; i < iCfgItemCnt; i++) {
        cnf = sk_CONF_VALUE_value(sect, i);
        rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value);
        if (rv > 0)
            continue;
        if (rv != -2) {
            fprintf(stderr, "Error processing %s = %s\n",
                    cnf->name, cnf->value);
            ERR_print_errors_fp(stderr);
            goto end;
        }
        if (strcmp(cnf->name, "Connect") == 0) {
            connect_str = cnf->value; /*!< 连接串从配置文件中来 */
            break;
        } else {
            /*! \bugfix 配置文件中还有多条配置项, 只有遍历完成后, 都没有找到, 才能说配置错误 */
            if ((iCfgItemCnt - 1) == i)
            {
                fprintf(stderr, "Unknown configuration option %s\n", cnf->name);
                goto end;
            }

            continue;
        }
    }

    /*!
    * 其他实现和 client - arg.c 相同
    */

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    /*
     * We'd normally set some stuff like the verify paths and * mode here
     * because as things stand this will connect to * any server whose
     * certificate is signed by any CA.
     */

    sbio = BIO_new_ssl_connect(ctx);

    BIO_get_ssl(sbio, &ssl);

    if (!ssl) {
        fprintf(stderr, "Can't locate SSL pointer\n");
        goto end;
    }

    /* We might want to do other things with ssl here */

    BIO_set_conn_hostname(sbio, connect_str);

    out = BIO_new_fp(stdout, BIO_NOCLOSE);
    if (BIO_do_connect(sbio) <= 0) {
        fprintf(stderr, "Error connecting to server\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    /* Could examine ssl here to get connection info */

    BIO_puts(sbio, "GET / HTTP/1.0\n\n");
    for (;;) {
        len = BIO_read(sbio, tmpbuf, 1024);
        if (len <= 0)
            break;
        BIO_write(out, tmpbuf, len);
    }
    ret = EXIT_SUCCESS;

 end:
    SSL_CONF_CTX_free(cctx);
    BIO_free_all(sbio);
    BIO_free(out);

    /*!
    * 由xx_new出来, 又没有附加到其他上下文的指针, 需要释放
    */
    NCONF_free(conf); /*! conf = NCONF_new() */
    return ret;
}

备注

openssl3.2 - 官方dmeo学习 - 索引贴

END

相关推荐
深耕AI13 天前
Win64OpenSSL-3_5_2.exe【安装步骤】
openssl
看那山瞧那水14 天前
DELPHI 利用OpenSSL实现加解密,证书(X.509)等功能
delphi·openssl
洋哥网络科技24 天前
openssl升级
openssl
Lazy Dave1 个月前
gmssl私钥文件格式
网络安全·ssl·openssl
沉在嵌入式的鱼2 个月前
RK3588移植Openssl库
linux·rk3588·openssl
黑屋里的马2 个月前
ssl相关命令生成证书
服务器·网络·ssl·openssl·gmssl
fangeqin2 个月前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
API开发3 个月前
苹果芯片macOS安装版Homebrew(亲测) ,一键安装node、python、vscode等,比绿色软件还干净、无污染
vscode·python·docker·nodejs·openssl·brew·homebrew
码农不惑3 个月前
Rust使用tokio(二)HTTPS相关
https·rust·web·openssl
liulilittle3 个月前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法并通过OPENSSL加密验证算法正确性。
linux·服务器·c++·算法·安全·加密·openssl