免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 8931 | 回复: 5
打印 上一主题 下一主题

CURL库怎样验证服务器证书 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-15 11:35 |只看该作者 |倒序浏览
我使用curl库怎样验证服务器证书,这里不必去验证客户证书。。。望大家指点(我英文不太好,翻半天文档也是一知半解)

论坛徽章:
0
2 [报告]
发表于 2008-10-15 11:55 |只看该作者
比如我用curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0);那就是说不验证对方的证书或者说验证肯定能通过,那么我应该怎样做才能验证对方服务器证书的有效性呢

论坛徽章:
0
3 [报告]
发表于 2012-11-14 15:55 |只看该作者
默认的好像是认证服务器的,客户端的不知道

论坛徽章:
0
4 [报告]
发表于 2012-11-14 17:52 |只看该作者
本帖最后由 seamine_cu 于 2012-11-14 17:57 编辑

去看看curl官方的例子http://curl.haxx.se/libcurl/c/cacertinmem.html
我把他的改了,改成从cacert.pem加载多个根证书列表,cacert.pem是根据http://curl.haxx.se/docs/caextract.html的方法下载或自己生成的
  1. /***************************************************************************
  2. *                                  _   _ ____  _
  3. *  Project                     ___| | | |  _ \| |
  4. *                             / __| | | | |_) | |
  5. *                            | (__| |_| |  _ <| |___
  6. *                             \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at http://curl.haxx.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. ***************************************************************************/
  22. /* Example using a "in core" PEM certificate to retrieve a https page.
  23. * Written by Theo Borm
  24. */

  25. /* on a netBSD system with OPENSSL& LIBCURL installed from
  26. * pkgsrc (using default paths) this program can be compiled using:
  27. * gcc -I/usr/pkg/include -L/usr/pkg/lib -lcurl -Wl,-R/usr/pkg/lib -lssl
  28. * -lcrypto -lz -o curlcacerttest curlcacerttest.c
  29. * on other operating systems you may want to change paths to headers
  30. * and libraries
  31. */
  32. #include <openssl/ssl.h>
  33. #include <curl/curl.h>
  34. #include <stdio.h>
  35. #include <string>
  36. #include <iostream>
  37. #include <fstream>
  38. #include <list>

  39. size_t writefunction( void *ptr, size_t size, size_t nmemb, void *stream)
  40. {
  41.   fwrite(ptr,size,nmemb,(FILE*)stream);
  42.   return(nmemb*size);
  43. }

  44. static CURLcode sslctx2_function(CURL * curl, void * sslctx, void * parm)
  45. {
  46.         char pem[65536] = {0};
  47.         X509_STORE * store;
  48.         X509 * cert=NULL;
  49.         BIO * bio = NULL;

  50.         std::fstream fs("D:\\cacert.pem");
  51.         std::string cert_text;
  52.         bool is_cert_begin = false;
  53.         std::list<std::string> certs;
  54.         const char cert_begin_text[] = "-----BEGIN CERTIFICATE-----";
  55.         const char cert_end_text[] = "-----END CERTIFICATE-----";

  56.         while (!fs.eof()) {
  57.                 memset(pem, 0, sizeof(pem));
  58.                 fs.getline(pem, sizeof(pem)-1);

  59.                 // ignore comment
  60.                 if (strncmp(pem, "#", 1) == 0) {
  61.                         continue;
  62.                 }
  63.                 if (strncmp(pem, cert_begin_text, sizeof(cert_begin_text)) == 0) {
  64.                         cert_text.clear();
  65.                         cert_text.append(pem);
  66.                         cert_text.append("\n");
  67.                         is_cert_begin = true;
  68.                         continue;
  69.                 }
  70.                 if (strncmp(pem, cert_end_text, sizeof(cert_end_text)) == 0) {
  71.                         cert_text.append(pem);
  72.                         cert_text.append("\n");
  73.                         certs.push_back(cert_text);
  74.                         cert_text.clear();
  75.                         is_cert_begin = false;
  76.                         continue;
  77.                 }
  78.                 if (is_cert_begin) {
  79.                         cert_text.append(pem);
  80.                         cert_text.append("\n");
  81.                 }
  82.         }

  83.         std::list<std::string>::iterator it = certs.begin();
  84.         while (it != certs.end()) {
  85.                 bio=BIO_new_mem_buf((void*)(it->c_str()), -1);
  86.                 /* use it to read the PEM formatted certificate from memory into an X509
  87.                  * structure that SSL can use
  88.                  */
  89.                 X509* px509 = PEM_read_bio_X509(bio, &cert, 0, NULL);
  90.                 if (cert == NULL) {
  91.                         printf("PEM_read_bio_X509 failed...\n");
  92.                 }

  93.                 /* get a pointer to the X509 certificate store (which may be empty!) */
  94.                 store=SSL_CTX_get_cert_store((SSL_CTX *)sslctx);

  95.                 /* add our certificate to this store */
  96.                 int ret = X509_STORE_add_cert(store, cert);
  97.                 if (ret == 0) {
  98.                         printf("error adding certificate\n");
  99.                 }

  100.                 X509_free(cert);
  101.                 cert = NULL;
  102.                 BIO_free(bio);
  103.                 bio = NULL;

  104.                 // next certificate
  105.                 ++it;
  106.         }

  107.         /* all set to go */
  108.         return CURLE_OK ;
  109. }

  110. static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
  111. {
  112.   X509_STORE * store;
  113.   X509 * cert=NULL;
  114.   BIO * bio;

  115.   char * mypem = // www.cacert.org
  116.     "-----BEGIN CERTIFICATE-----\n"\
  117.     "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
  118.     "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
  119.     "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\
  120.     "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\
  121.     "BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\
  122.     "MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\
  123.     "ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\
  124.     "CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\
  125.     "8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\
  126.     "zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\
  127.     "fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\
  128.     "w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\
  129.     "G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\
  130.     "epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\
  131.     "laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\
  132.     "QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\
  133.     "fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\
  134.     "YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\
  135.     "ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\
  136.     "gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\
  137.     "MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\
  138.     "IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\
  139.     "dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\
  140.     "czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\
  141.     "dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\
  142.     "aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\
  143.     "AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\
  144.     "b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\
  145.     "ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\
  146.     "nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\
  147.     "18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\
  148.     "gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\
  149.     "Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\
  150.     "sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\
  151.     "SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\
  152.     "CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\
  153.     "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\
  154.     "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\
  155.     "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
  156.     "-----END CERTIFICATE-----\n";

  157.   /* get a BIO */
  158.   bio=BIO_new_mem_buf(mypem, -1);
  159.   /* use it to read the PEM formatted certificate from memory into an X509
  160.    * structure that SSL can use
  161.    */
  162.   PEM_read_bio_X509(bio, &cert, 0, NULL);
  163.   if (cert == NULL)
  164.     printf("PEM_read_bio_X509 failed...\n");

  165.   /* get a pointer to the X509 certificate store (which may be empty!) */
  166.   store=SSL_CTX_get_cert_store((SSL_CTX *)sslctx);

  167.   /* add our certificate to this store */
  168.   if (X509_STORE_add_cert(store, cert)==0)
  169.     printf("error adding certificate\n");

  170.   /* all set to go */
  171.   return CURLE_OK ;
  172. }

  173. int main(void)
  174. {
  175.   CURL * ch;
  176.   CURLcode rv;

  177.   rv=curl_global_init(CURL_GLOBAL_ALL);
  178.   ch=curl_easy_init();
  179.   rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 0L);
  180.   rv=curl_easy_setopt(ch,CURLOPT_HEADER, 0L);
  181.   rv=curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L);
  182.   rv=curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L);
  183.   rv=curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);
  184.   rv=curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);
  185.   rv=curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);
  186.   rv=curl_easy_setopt(ch,CURLOPT_WRITEHEADER, stderr);
  187.   rv=curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");
  188.   rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER,1L);
  189.   rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYHOST, 2L);
  190.   rv=curl_easy_setopt(ch,CURLOPT_URL, "https://www.dropbox.com/");
  191.   rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 1);

  192.   /* first try: retrieve page without cacerts' certificate -> will fail
  193.    */
  194.   /*
  195.   rv=curl_easy_perform(ch);
  196.   if (rv==CURLE_OK)
  197.     printf("*** transfer succeeded ***\n");
  198.   else
  199.     printf("*** transfer failed ***\n");
  200. */
  201.   /* second try: retrieve page using cacerts' certificate -> will succeed
  202.    * load the certificate by installing a function doing the nescessary
  203.    * "modifications" to the SSL CONTEXT just before link init
  204.    */
  205.   //rv = curl_easy_setopt(ch, CURLOPT_CAPATH, "d:\\");
  206.   //rv = curl_easy_setopt(ch, CURLOPT_CAINFO, "d:\\cacert.pem");
  207.   //rv = curl_easy_setopt(ch, CURLOPT_CERTINFO, 1L);
  208.   rv=curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx2_function);
  209.   rv=curl_easy_perform(ch);
  210.   if (rv==CURLE_OK)
  211.     printf("*** transfer succeeded ***\n");
  212.   else
  213.     printf("*** transfer failed ***\n");

  214.   curl_easy_cleanup(ch);
  215.   curl_global_cleanup();
  216.   return rv;
  217. }
复制代码

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
5 [报告]
发表于 2012-11-14 19:29 |只看该作者
本帖最后由 linux_c_py_php 于 2012-11-14 19:30 编辑

你是客户端, 你希望的是: 你拿着服务端传给你的证书, 去CA问证书的合法性, 合法你就继续通信, 否则不和服务端通信了.
  1. CURLOPT_SSL_VERIFYHOST

  2. Pass a long as parameter.

  3. This option determines whether libcurl verifies that the server cert is for the server it is known as.

  4. When negotiating a SSL connection, the server sends a certificate indicating its identity.

  5. When CURLOPT_SSL_VERIFYHOST is 2, that certificate must indicate that the server is the server to which you meant to connect, or the connection fails.

  6. Curl considers the server the intended one when the Common Name field or a Subject Alternate Name field in the certificate matches the host name in the URL to which you told Curl to connect.

  7. When the value is 1, libcurl will return a failure. It was previously (in 7.28.0 and earlier) a debug option of some sorts, but it is no longer supported due to frequently leading to programmer mistakes.

  8. When the value is 0, the connection succeeds regardless of the names in the certificate.

  9. The default value for this option is 2.

  10. This option controls checking the server's certificate's claimed identity. The server could be lying. To control lying, see CURLOPT_SSL_VERIFYPEER. If libcurl is built against NSS and CURLOPT_SSL_VERIFYPEER is zero, CURLOPT_SSL_VERIFYHOST is ignored.
复制代码
  1. CURLOPT_SSL_VERIFYPEER

  2. Pass a long as parameter. By default, curl assumes a value of 1.

  3. This option determines whether curl verifies the authenticity of the peer's certificate. A value of 1 means curl verifies; 0 (zero) means it doesn't.

  4. When negotiating a SSL connection, the server sends a certificate indicating its identity. Curl verifies whether the certificate is authentic, i.e. that you can trust that the server is who the certificate says it is. This trust is based on a chain of digital signatures, rooted in certification authority (CA) certificates you supply. curl uses a default bundle of CA certificates (the path for that is determined at build time) and you can specify alternate certificates with the CURLOPT_CAINFO option or the CURLOPT_CAPATH option.

  5. When CURLOPT_SSL_VERIFYPEER is nonzero, and the verification fails to prove that the certificate is authentic, the connection fails. When the option is zero, the peer certificate verification succeeds regardless.

  6. Authenticating the certificate is not by itself very useful. You typically want to ensure that the server, as authentically identified by its certificate, is the server you mean to be talking to. Use CURLOPT_SSL_VERIFYHOST to control that. The check that the host name in the certificate is valid for the host name you're connecting to is done independently of the CURLOPT_SSL_VERIFYPEER option.
复制代码

论坛徽章:
0
6 [报告]
发表于 2012-11-15 09:04 |只看该作者
linux_c_py_php 发表于 2012-11-14 19:29
你是客户端, 你希望的是: 你拿着服务端传给你的证书, 去CA问证书的合法性, 合法你就继续通信, 否则不和服务 ...



So, 这个例子是客户端的啊。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP