mosquitto使用TLS安全连接预置客户端证书密码

最近在使用mosquitto做项目,使用TLS安全连接,并且客户端证书需要密码,在使用mosquitto_pub/mosquitto_sub命令是终端出输入证书密码的提示:Enter PEM pass phrase:
为了解决手动输入密码的问题我搜索此打印找到如下函数

int PEM_def_callback(char *buf, int num, int rwflag, void *userdata)
{
    int i, min_len;
    const char *prompt;

    /* We assume that the user passes a default password as userdata */
    if (userdata) {
        i = strlen(userdata);
        i = (i > num) ? num : i;
        memcpy(buf, userdata, i);
        return i;
    }

    prompt = EVP_get_pw_prompt();
    if (prompt == NULL)
        prompt = "1.1.1 Enter PEM pass phrase:";

    /*
     * rwflag == 0 means decryption
     * rwflag == 1 means encryption
     *
     * We assume that for encryption, we want a minimum length, while for
     * decryption, we cannot know any minimum length, so we assume zero.
     */
    min_len = rwflag ? MIN_LENGTH : 0;

    i = EVP_read_pw_string_min(buf, min_len, num, prompt, rwflag);
    if (i != 0) {
        PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
        memset(buf, 0, (unsigned int)num);
        return -1;
    }
    return strlen(buf);
}


 EVP_get_pw_prompt()获取预置密码,如果没有预置密码则进入EVP_read_pw_string_min函数由用户手动输入,顺藤摸瓜又找到了设置预置密码的函数

 /* should be init to zeros. */
static char prompt_string[80];

void EVP_set_pw_prompt(const char *prompt)
{
    if (prompt == NULL)
        prompt_string[0] = '\0';
    else {
        strncpy(prompt_string, prompt, 79);
        prompt_string[79] = '\0';
    }
}


看到此处豁然开朗,如果预置密码,调用EVP_set_pw_prompt函数即可提前设置密码,但是我调用此函数之后再运行mosquitto_pub/mosquitto_sub命令,终端只是把预置的密码回显到终端,并不会继续执行。再敲个回车,直接挂死。头疼十分钟。
于是又想找到在哪里获取手动输入的密码,找了半天看不懂i = EVP_read_pw_string_min(buf, min_len, num, prompt, rwflag)函数,里面好多函数找不到哪里定义,放弃之。于是想是不是EVP_read_pw_string_min函数对预置密码处理有问题,当前使用openssl为1.1.1,到了之后的新版本是不是解决这个bug了?于是又编译了openssl3.0.0,依然是这个样子,于是尝试将代码改成如下形式,不使用自带的EVP_read_pw_string_min函数,如果有预置密码直接拷贝到buf中,试了一下果然成功。

int PEM_def_callback(char *buf, int num, int rwflag, void *userdata)
{
    int i, min_len;
    const char *prompt;

    /* We assume that the user passes a default password as userdata */
    if (userdata) {
        i = strlen(userdata);
        i = (i > num) ? num : i;
        memcpy(buf, userdata, i);
        return i;
    }
    
    prompt = EVP_get_pw_prompt();
    if (prompt == NULL){
        prompt = "Enter PEM pass phrase:";
        /*
        * rwflag == 0 means decryption
        * rwflag == 1 means encryption
        *
        * We assume that for encryption, we want a minimum length, while for
        * decryption, we cannot know any minimum length, so we assume zero.
        */
        min_len = rwflag ? MIN_LENGTH : 0;
        i = EVP_read_pw_string_min(buf, min_len, num, prompt, rwflag);
        if (i != 0) {
            PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
            memset(buf, 0, (unsigned int)num);
            return -1;
        }
    }else
    {
        strncpy(buf, prompt, num);
        buf[num-1] = '\0';
    }
    return strlen(buf);
}

后来又在github问了这个问题给出的回复是我的方法不对。。。。。

正确的方法应该是设置PEM密码回调函数

int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
{
	strncpy(buf, "123456", size);
	buf[size - 1] = '\0';
	return(strlen(buf));
}

int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
{
......
#ifdef WITH_TLS
	if(cfg->cafile || cfg->capath){
		rc = mosquitto_tls_set(mosq, cfg->cafile, cfg->capath, cfg->certfile, cfg->keyfile, pem_passwd_cb);

......
}

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值