Tongsuo icon indicating copy to clipboard operation
Tongsuo copied to clipboard

国密ssl

Open ccutyang0569 opened this issue 2 years ago • 3 comments

国密实验室版本的openssl 是不需要修改nginx的,但是有许可时间限制, babssl能提供类似这样的国密ssl支持吗? 即使用标准的nginx 使用Babassl 编译安装 实现国密ssl

ccutyang0569 avatar Jul 29 '22 08:07 ccutyang0569

不改nginx的话,我理解配置双证书的话只能复用nginx目前的directive,这样一来配置就会不清晰,所以我们选择的是增加新NGINX directive的路线

InfoHunter avatar Aug 01 '22 02:08 InfoHunter

不改nginx的话,我理解配置双证书的话只能复用nginx目前的directive,这样一来配置就会不清晰,所以我们选择的是增加新NGINX directive的路线

后面我们可以考虑提供 nginx 的 patch,这样 nginx 用户就比较容易使用了

wa5i avatar Aug 01 '22 02:08 wa5i

一个可能可行的方案

  • 新版nginx(自从1.19.x?)提供了ssl_conf_command用于对ssl上下文的配置能力
  • 目前Tongsuo实现了基于SSL_CONF_CMD的ntls配置命令,如下
// ssl/ssl_conf.c

#ifndef OPENSSL_NO_NTLS
    SSL_CONF_CMD_STRING(Enable_ntls, "enable_ntls", 0),
    SSL_CONF_CMD(EncCertificate, "enc_cert", SSL_CONF_FLAG_CERTIFICATE,
                 SSL_CONF_TYPE_FILE),
    SSL_CONF_CMD(EncPrivateKey, "enc_key", SSL_CONF_FLAG_CERTIFICATE,
                 SSL_CONF_TYPE_FILE),
    SSL_CONF_CMD(SignCertificate, "sign_cert", SSL_CONF_FLAG_CERTIFICATE,
                 SSL_CONF_TYPE_FILE),
    SSL_CONF_CMD(SignPrivateKey, "sign_key", SSL_CONF_FLAG_CERTIFICATE,
                 SSL_CONF_TYPE_FILE),
#endif

此方案已验证ntls+tls场景可直接应用,由于没有实现ntls_method相关api的配置,因此暂时无法配置ntls-only场景

我通过一个补丁为Tongsuo增加了一个命令,用于将ssl_ctx内部的method替换为ntls_method,以实现ntls-only场景支持,大致逻辑如下:

...

static int cmd_Enable_ntls2(SSL_CONF_CTX *cctx, const char *value)
{
    if (strcmp(value, "on") == 0) {
        if (cctx->ctx) {
            cctx->ctx->enable_ntls = 1;
            if (cctx->ctx->back_method) {
                cctx->ctx->method = cctx->ctx->back_method;
                cctx->ctx->back_method = NULL;
            }
        }
    } else if (strcmp(value, "on:ntls_client_method") == 0) {
        if (cctx->ctx) {
            cctx->ctx->enable_ntls = 1;
            if (!cctx->ctx->back_method) {
                cctx->ctx->back_method = cctx->ctx->method;
            }
            cctx->ctx->method = ntls_client_method();
        }
    } else if (strcmp(value, "on:ntls_server_method") == 0) {
        if (cctx->ctx) {
            cctx->ctx->enable_ntls = 1;
            if (!cctx->ctx->back_method) {
                cctx->ctx->back_method = cctx->ctx->method;
            }
            cctx->ctx->method = ntls_server_method();
        }
    } else if (strcmp(value, "on:ntls_method") == 0) {
        if (cctx->ctx) {
            cctx->ctx->enable_ntls = 1;
            if (!cctx->ctx->back_method) {
                cctx->ctx->back_method = cctx->ctx->method;
            }
            cctx->ctx->method = ntls_method();
        }
    } else {
        if (cctx->ctx) {
            cctx->ctx->enable_ntls = 0;
            if (cctx->ctx->back_method) {
                cctx->ctx->method = cctx->ctx->back_method;
                cctx->ctx->back_method = NULL;
            }
        }
    }
    return 1;
}

...

SSL_CONF_CMD_STRING(Enable_ntls2, "enable_ntls2", 0),

...

nginx配置如下:

        # 增加TLSv1.3协议
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

#if 国密兼容 || 仅国际套件
        ssl_ciphers  SM1:SM4:SMS4:AES128:AES256:-MD5:-SHA1:-DH;
#else
        ssl_ciphers  SM1:SM4:SMS4:-MD5:-SHA1:-DH:-SHA256:-SHA384:-RSA;
#endif

#if 仅国密套件 || 仅国密双证书套件
        ssl_conf_command Ciphersuites TLS_SM4_GCM_SM3:TLS_SM4_CCM_SM3;
#endif

#if 国密兼容 || 仅国密套件 || 仅国密双证书套件
#if 仅国密双证书套件
        ssl_conf_command Enable_ntls2       on:ntls_method;
#else
        ssl_conf_command Enable_ntls2       on;
#endif
        ssl_conf_command EncCertificate    /usr/local/nginx/conf/certs/se.crt;
        ssl_conf_command EncPrivateKey     /usr/local/nginx/conf/certs/se.key;
        ssl_conf_command SignCertificate   /usr/local/nginx/conf/certs/ss.crt;
        ssl_conf_command SignPrivateKey    /usr/local/nginx/conf/certs/ss.key;
#endif

#if 国密兼容 || 仅国际套件
        ssl_certificate      /usr/local/nginx/conf/certs/rsa.crt;
        ssl_certificate_key  /usr/local/nginx/conf/certs/rsa.key;
#endif

#if 国密兼容 || 仅国密套件 || 仅国密双证书套件
        ssl_certificate      /usr/local/nginx/conf/certs/ss.crt;
        ssl_certificate_key  /usr/local/nginx/conf/certs/ss.key;
#endif

#if 双向认证
        ssl_verify_client on;
        ssl_client_certificate /usr/local/nginx/conf/certs/ca.crt;
#endif

@InfoHunter 可以考虑一下这个方案,补齐ntls-only场景支持

daipingh avatar Sep 21 '22 02:09 daipingh