CURL组建中,HTTPS使用ip地址连接时候,SSL安全验证方法!

1.背景

1.苹果最近调整了HTTP连接的思路,要求iOS开发代码中所有的http连接都必须使用,https安全连接方式。

2.在实现HTTP服务中,会有种VIP的保障逻辑。在域名解析失败(DNS劫持是其中一种情况)而无法连接时候,会内置ip地址,保证在最坏的情况下,可以连通服务。

那么问题来了,HTTPS直接使用HOST为ip地址的时候,是无法正确使用SSL校验安全证书的,因为证书和域名绑定。

2.环境

curl组件c实现库,iOS开发工程

3.方案

实现方式只是在现有curl组件实现的,http逻辑逻辑基础上补充。具体完整curl实现http请求逻辑,待补充。

原理:通过IP直接访问网站,解决DNS劫持问题。DNS劫持中,对于HTTPS请求,有SSL校验安全证书的过程,这个时候HOST参数对应的域名是被绑定到证书上,进行安全校验,而IP是无法通过校验的。这个时候只有在SSL校验之前修改HOST参数为实际绑定的域名,才能完成SSL安全校验。这个时候就涉及到CURL组件里面setOption(CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);设置。找到在SSL校验之前修改参数的时机,具体实现如下。


添加代码以及调试逻辑主要是在初始化时候添加如下三行代码:

  setOption(CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
        setOption(CURLOPT_DEBUGFUNCTION, my_trace);
        setOption(CURLOPT_VERBOSE, 1L); 

sslctx_function 和 my_trace 方法逻辑如下:
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
{
    if (curl) {XXX
        struct curl_slist *list = NULL;
        list = curl_slist_append(list, "Host: XXX.XXX.XXX.XXX:8888");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
    }
    
    /* all set to go */
    return CURLE_OK;
}

static int my_trace(CURL *handle, curl_infotype type, char *data, size_t size, void *userp)
{
    const char *text;
    (void)handle; /* prevent compiler warning */
    (void)userp;
    
    char buf[1024] = {0};
    snprintf(buf, size, "%s type %d", data, type);
    mylog("%s", buf);
    
    switch (type) {
        case CURLINFO_TEXT:
            fprintf(stderr, "== Info: %s", data);
        default: /* in case a new one is introduced to shock us */
            return 0;
            
        case CURLINFO_HEADER_OUT:
            text = "=> Send header";
            break;
        case CURLINFO_DATA_OUT:
            text = "=> Send data";
            break;
        case CURLINFO_SSL_DATA_OUT:
            text = "=> Send SSL data";
            break;
        case CURLINFO_HEADER_IN:
            text = "<= Recv header";
            break;
        case CURLINFO_DATA_IN:
            text = "<= Recv data";
            break;
        case CURLINFO_SSL_DATA_IN:
            text = "<= Recv SSL data";
            break;
    }
    
    if (text)
mylog("== %s", text);
    }
    
//    dump(text, stderr, (unsigned char *)data, size);
    return 0;

4.结论

5.参考

curl中日志追踪实现 -- https://curl.haxx.se/libcurl/c/CURLOPT_DEBUGFUNCTION.html

实现思路参考 -- https://github.com/tencentyun/httpdns-ios-sdk


你可能感兴趣的:(iOS,cocos2dx,https)