libcurl使用默认编译的winssl进行https的双向认证

双向认证:

1.服务器回验证客户端上报的证书

2.客户端回验证服务器的证书

而证书一般分为:1.受信任的根证书,2不受信任的根证书。

但是由于各种限制不想在libcurl中增加openssl,那么使用默认的winssl也可以完成以上两种证书的双向认证,以下是亲测代码:

static int http_write(char* data, size_t size, size_t nmemb, std::string* writerData)
{
    unsigned long sizes = size * nmemb;
    if (writerData == NULL)
        return-1;
    writerData->append(data, sizes);
    return sizes;
}

int main_curl(void)
{
    CURL* curl;
    CURLcode res = CURLE_OK;
    const char* pPassphrase = NULL;    //password for private key

    static const char* pCACertFile = "C:\\ca.crt"; //CA root certificat
    static const char* pCertFile = "C:\\client.p12"; //client certificate
    static const char* pKeyName = "C:\\client.key";        // private.key

    static const char* pHeaderFile = "dumpit";

    const char* pKeyType;

    const char* pEngine;

    pKeyType = "PEM";
    pEngine = NULL;

    std::string sRes;

    char* url = "https://xxx.com";

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
        /* what call to write: */
        curl_easy_setopt(curl, CURLOPT_URL, url);

        do { /* dummy loop, just to break out from */
            if (pEngine) {
                /* use crypto engine */
                if (curl_easy_setopt(curl, CURLOPT_SSLENGINE, pEngine) != CURLE_OK) {
                    /* load the crypto engine */
                    fprintf(stderr, "can't set crypto engine\n");
                    break;
                }
                if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != CURLE_OK) {
                    /* set the crypto engine as default */
                    /* only needed for the first time you load
           *              a engine in a curl object... */
                    fprintf(stderr, "can't set crypto engine as default\n");
                    break;
                }
            }

            //winssl 必须是P12证书类型,不能设置其参数,openssl下可以设置
            //curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");

            /* 客户端证书 */
            curl_easy_setopt(curl, CURLOPT_SSLCERT, pCertFile);
            
            /* 设置客户端证书的key和类型*/
            curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
            curl_easy_setopt(curl, CURLOPT_SSLKEY, pKeyName);            

            /* 验证服务器需要的根证书 */
            curl_easy_setopt(curl, CURLOPT_CAINFO, pCACertFile);       

            /* 自签名证书不要验证对端 */
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);

            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_write);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &sRes);

            /* Perform the request, res will get the return code */
            res = curl_easy_perform(curl);
            /* Check for errors */
            if (res != CURLE_OK)
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                        curl_easy_strerror(res));

        } while (0);
        /* always cleanup */
        curl_easy_cleanup(curl);
    }

    std::cout<<"RESPONSE HTML:" << sRes;

    return (res == CURLE_OK);
}

以上的代码如果根证书是受信任的,设置

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);

自签证书设置:

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);

即可完成winssl的双向认证;

你可能感兴趣的:(libcurl,https,winssl,libcurl,双向认证)