25 #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ 26 defined(USE_CYASSL) || defined(USE_SCHANNEL) 44 #define CURL_SIZE_T_MAX ((size_t)-1) 48 static const char cnOID[] =
"2.5.4.3";
49 static const char sanOID[] =
"2.5.29.17";
51 static const curl_OID OIDtable[] = {
52 {
"1.2.840.10040.4.1",
"dsa" },
53 {
"1.2.840.10040.4.3",
"dsa-with-sha1" },
54 {
"1.2.840.10045.2.1",
"ecPublicKey" },
55 {
"1.2.840.10045.3.0.1",
"c2pnb163v1" },
56 {
"1.2.840.10045.4.1",
"ecdsa-with-SHA1" },
57 {
"1.2.840.10046.2.1",
"dhpublicnumber" },
58 {
"1.2.840.113549.1.1.1",
"rsaEncryption" },
59 {
"1.2.840.113549.1.1.2",
"md2WithRSAEncryption" },
60 {
"1.2.840.113549.1.1.4",
"md5WithRSAEncryption" },
61 {
"1.2.840.113549.1.1.5",
"sha1WithRSAEncryption" },
62 {
"1.2.840.113549.1.1.10",
"RSASSA-PSS" },
63 {
"1.2.840.113549.1.1.14",
"sha224WithRSAEncryption" },
64 {
"1.2.840.113549.1.1.11",
"sha256WithRSAEncryption" },
65 {
"1.2.840.113549.1.1.12",
"sha384WithRSAEncryption" },
66 {
"1.2.840.113549.1.1.13",
"sha512WithRSAEncryption" },
67 {
"1.2.840.113549.2.2",
"md2" },
68 {
"1.2.840.113549.2.5",
"md5" },
69 {
"1.3.14.3.2.26",
"sha1" },
72 {
"2.5.4.5",
"serialNumber" },
76 {
"2.5.4.9",
"streetAddress" },
79 {
"2.5.4.12",
"title" },
80 {
"2.5.4.13",
"description" },
81 {
"2.5.4.17",
"postalCode" },
82 {
"2.5.4.41",
"name" },
83 {
"2.5.4.42",
"givenName" },
84 {
"2.5.4.43",
"initials" },
85 {
"2.5.4.44",
"generationQualifier" },
86 {
"2.5.4.45",
"X500UniqueIdentifier" },
87 {
"2.5.4.46",
"dnQualifier" },
88 {
"2.5.4.65",
"pseudonym" },
89 {
"1.2.840.113549.1.9.1",
"emailAddress" },
90 {
"2.5.4.72",
"role" },
91 { sanOID,
"subjectAltName" },
92 {
"2.5.29.18",
"issuerAltName" },
93 {
"2.5.29.19",
"basicConstraints" },
94 {
"2.16.840.1.101.3.4.2.4",
"sha224" },
95 {
"2.16.840.1.101.3.4.2.1",
"sha256" },
96 {
"2.16.840.1.101.3.4.2.2",
"sha384" },
97 {
"2.16.840.1.101.3.4.2.3",
"sha512" },
98 { (
const char *) NULL, (
const char *) NULL }
111 const char *Curl_getASN1Element(curl_asn1Element *elem,
112 const char *beg,
const char *end)
116 curl_asn1Element lelem;
122 if(!beg || !end || beg >= end || !*beg ||
123 (
size_t)(end - beg) > CURL_ASN1_MAX)
124 return (
const char *) NULL;
128 b = (
unsigned char) *beg++;
129 elem->constructed = (b & 0x20) != 0;
130 elem->class = (b >> 6) & 3;
133 return (
const char *) NULL;
138 return (
const char *) NULL;
139 b = (
unsigned char) *beg++;
142 else if(!(b &= 0x7F)) {
145 if(!elem->constructed)
146 return (
const char *) NULL;
148 while(beg < end && *beg) {
149 beg = Curl_getASN1Element(&lelem, beg, end);
151 return (
const char *) NULL;
154 return (
const char *) NULL;
158 else if((
unsigned)b > (
size_t)(end - beg))
159 return (
const char *) NULL;
164 if(len & 0xFF000000L)
165 return (
const char *) NULL;
166 len = (len << 8) | (
unsigned char) *beg++;
169 if(len > (
size_t)(end - beg))
170 return (
const char *) NULL;
172 elem->end = beg +
len;
176 static const curl_OID * searchOID(
const char *oid)
183 for(op = OIDtable; op->numoid; op++)
187 return (
const curl_OID *) NULL;
190 static const char *bool2str(
const char *beg,
const char *end)
197 return (
const char *) NULL;
198 return strdup(*beg?
"TRUE":
"FALSE");
201 static const char *octet2str(
const char *beg,
const char *end)
203 size_t n = end - beg;
209 if(n <= (CURL_SIZE_T_MAX - 1) / 3) {
212 for(n = 0; beg < end; n += 3)
213 snprintf(buf + n, 4,
"%02x:", *(
const unsigned char *) beg++);
218 static const char *bit2str(
const char *beg,
const char *end)
224 return (
const char *) NULL;
225 return octet2str(beg, end);
228 static const char *int2str(
const char *beg,
const char *end)
231 size_t n = end - beg;
238 return (
const char *) NULL;
241 return octet2str(beg, end);
248 val = (val << 8) | *(
const unsigned char *) beg++;
250 return curl_maprintf(
"%s%lx", (val < 0 || val >= 10)?
"0x":
"", val);
254 utf8asn1str(
char **to,
int type,
const char *
from,
const char *end)
256 size_t inlength = end -
from;
271 case CURL_ASN1_BMP_STRING:
274 case CURL_ASN1_UNIVERSAL_STRING:
277 case CURL_ASN1_NUMERIC_STRING:
278 case CURL_ASN1_PRINTABLE_STRING:
279 case CURL_ASN1_TELETEX_STRING:
280 case CURL_ASN1_IA5_STRING:
281 case CURL_ASN1_VISIBLE_STRING:
282 case CURL_ASN1_UTF8_STRING:
290 if(inlength / size > (CURL_SIZE_T_MAX - 1) / 4)
292 buf =
malloc(4 * (inlength / size) + 1);
296 if(type == CURL_ASN1_UTF8_STRING) {
298 outlength = inlength;
300 memcpy(buf, from, outlength);
303 for(outlength = 0; from < end;) {
307 wc = (wc << 8) | *(
const unsigned char *) from++;
308 wc = (wc << 8) | *(
const unsigned char *) from++;
311 wc = (wc << 8) | *(
const unsigned char *) from++;
314 wc = (wc << 8) | *(
const unsigned char *) from++;
317 if(wc >= 0x00000080) {
318 if(wc >= 0x00000800) {
319 if(wc >= 0x00010000) {
320 if(wc >= 0x00200000) {
324 buf[outlength + 3] = (char) (0x80 | (wc & 0x3F));
325 wc = (wc >> 6) | 0x00010000;
328 buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
329 wc = (wc >> 6) | 0x00000800;
332 buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
333 wc = (wc >> 6) | 0x000000C0;
336 buf[outlength] = (char) wc;
337 outlength += charsize;
340 buf[outlength] =
'\0';
345 static const char *string2str(
int type,
const char *beg,
const char *end)
352 if(utf8asn1str(&buf, type, beg, end) < 0)
353 return (
const char *) NULL;
357 static int encodeUint(
char *buf,
int n,
unsigned int x)
360 unsigned int y = x / 10;
366 i += encodeUint(buf, n, y);
370 buf[
i] = (char) (
'0' + x);
377 static int encodeOID(
char *buf,
int n,
const char *beg,
const char *end)
388 y = *(
const unsigned char *) beg++;
391 i += encodeUint(buf + i, n - i, x);
395 i += encodeUint(buf + i, n - i, y);
406 y = *(
const unsigned char *) beg++;
407 x = (x << 7) | (y & 0x7F);
409 i += encodeUint(buf + i, n - i, x);
416 static const char *OID2str(
const char *beg,
const char *end,
bool symbolic)
418 char *buf = (
char *) NULL;
426 n = encodeOID((
char *) NULL, -1, beg, end);
430 encodeOID(buf, n, beg, end);
437 buf =
strdup(op->textoid);
446 static const char *GTime2str(
const char *beg,
const char *end)
453 const char *sep =
"";
458 for(fracp = beg; fracp < end && *fracp >=
'0' && *fracp <=
'9'; fracp++)
463 switch(fracp - beg - 12) {
474 return (
const char *) NULL;
480 if(fracp < end && (*fracp ==
'.' || *fracp ==
',')) {
484 while(tzp < end && *tzp >=
'0' && *tzp <=
'9');
486 for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] ==
'0'; fracl--)
493 else if(*tzp ==
'Z') {
503 return curl_maprintf(
"%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s",
504 beg, beg + 4, beg + 6,
505 beg + 8, beg + 10, sec1, sec2,
506 fracl?
".":
"", fracl, fracp,
510 static const char *UTime2str(
const char *beg,
const char *end)
519 for(tzp = beg; tzp < end && *tzp >=
'0' && *tzp <=
'9'; tzp++)
529 return (
const char *) NULL;
534 return (
const char *) NULL;
544 20 - (*beg >=
'5'), beg, beg + 2, beg + 4,
545 beg + 6, beg + 8, sec,
549 const char *Curl_ASN1tostr(curl_asn1Element *elem,
int type)
554 if(elem->constructed)
555 return (
const char *) NULL;
561 case CURL_ASN1_BOOLEAN:
562 return bool2str(elem->beg, elem->end);
563 case CURL_ASN1_INTEGER:
564 case CURL_ASN1_ENUMERATED:
565 return int2str(elem->beg, elem->end);
566 case CURL_ASN1_BIT_STRING:
567 return bit2str(elem->beg, elem->end);
568 case CURL_ASN1_OCTET_STRING:
569 return octet2str(elem->beg, elem->end);
572 case CURL_ASN1_OBJECT_IDENTIFIER:
573 return OID2str(elem->beg, elem->end,
TRUE);
574 case CURL_ASN1_UTC_TIME:
575 return UTime2str(elem->beg, elem->end);
576 case CURL_ASN1_GENERALIZED_TIME:
577 return GTime2str(elem->beg, elem->end);
578 case CURL_ASN1_UTF8_STRING:
579 case CURL_ASN1_NUMERIC_STRING:
580 case CURL_ASN1_PRINTABLE_STRING:
581 case CURL_ASN1_TELETEX_STRING:
582 case CURL_ASN1_IA5_STRING:
583 case CURL_ASN1_VISIBLE_STRING:
584 case CURL_ASN1_UNIVERSAL_STRING:
585 case CURL_ASN1_BMP_STRING:
586 return string2str(type, elem->beg, elem->end);
589 return (
const char *) NULL;
592 static ssize_t encodeDN(
char *buf,
size_t n, curl_asn1Element *dn)
594 curl_asn1Element rdn;
595 curl_asn1Element atv;
596 curl_asn1Element oid;
597 curl_asn1Element
value;
607 for(p1 = dn->beg; p1 < dn->end;) {
608 p1 = Curl_getASN1Element(&rdn, p1, dn->end);
609 for(p2 = rdn.beg; p2 < rdn.end;) {
610 p2 = Curl_getASN1Element(&atv, p2, rdn.end);
611 p3 = Curl_getASN1Element(&oid, atv.beg, atv.end);
612 Curl_getASN1Element(&value, p3, atv.end);
613 str = Curl_ASN1tostr(&oid, 0);
620 for(p3 = str; isupper(*p3); p3++)
622 for(p3 = (*p3 || p3 - str > 2)?
"/":
", "; *p3; p3++) {
630 for(p3 = str; *p3; p3++) {
643 str = Curl_ASN1tostr(&value, 0);
646 for(p3 = str; *p3; p3++) {
658 const char *Curl_DNtostr(curl_asn1Element *dn)
660 char *buf = (
char *) NULL;
661 ssize_t n = encodeDN(buf, 0, dn);
669 encodeDN(buf, n + 1, dn);
673 return (
const char *)
buf;
680 int Curl_parseX509(curl_X509certificate *cert,
681 const char *beg,
const char *end)
683 curl_asn1Element elem;
684 curl_asn1Element tbsCertificate;
686 static const char defaultVersion = 0;
692 cert->certificate.header = NULL;
693 cert->certificate.beg = beg;
694 cert->certificate.end = end;
697 if(!Curl_getASN1Element(&elem, beg, end))
703 beg = Curl_getASN1Element(&tbsCertificate, beg, end);
705 beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
707 Curl_getASN1Element(&cert->signature, beg, end);
710 beg = tbsCertificate.beg;
711 end = tbsCertificate.end;
713 cert->version.header = NULL;
714 cert->version.beg = &defaultVersion;
715 cert->version.end = &defaultVersion +
sizeof defaultVersion;;
716 beg = Curl_getASN1Element(&elem, beg, end);
718 Curl_getASN1Element(&cert->version, elem.beg, elem.end);
719 beg = Curl_getASN1Element(&elem, beg, end);
721 cert->serialNumber = elem;
723 beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
725 beg = Curl_getASN1Element(&cert->issuer, beg, end);
727 beg = Curl_getASN1Element(&elem, beg, end);
728 ccp = Curl_getASN1Element(&cert->notBefore, elem.beg, elem.end);
729 Curl_getASN1Element(&cert->notAfter, ccp, elem.end);
731 beg = Curl_getASN1Element(&cert->subject, beg, end);
733 beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
734 ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
735 cert->subjectPublicKeyInfo.beg,
736 cert->subjectPublicKeyInfo.end);
737 Curl_getASN1Element(&cert->subjectPublicKey, ccp,
738 cert->subjectPublicKeyInfo.end);
740 cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
741 cert->extensions.tag = elem.tag = 0;
742 cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL;
743 cert->issuerUniqueID.beg = cert->issuerUniqueID.end =
"";
744 cert->subjectUniqueID.beg = cert->subjectUniqueID.end =
"";
745 cert->extensions.header = NULL;
746 cert->extensions.beg = cert->extensions.end =
"";
748 beg = Curl_getASN1Element(&elem, beg, end);
750 cert->issuerUniqueID = elem;
752 beg = Curl_getASN1Element(&elem, beg, end);
755 cert->subjectUniqueID = elem;
757 beg = Curl_getASN1Element(&elem, beg, end);
760 Curl_getASN1Element(&cert->extensions, elem.beg, elem.end);
764 static size_t copySubstring(
char *to,
const char *from)
771 for(i = 0; i < 64; i++) {
781 static const char *dumpAlgo(curl_asn1Element *param,
782 const char *beg,
const char *end)
784 curl_asn1Element oid;
788 beg = Curl_getASN1Element(&oid, beg, end);
789 param->header = NULL;
791 param->beg = param->end = end;
793 Curl_getASN1Element(param, beg, end);
794 return OID2str(oid.beg, oid.end,
TRUE);
797 static void do_pubkey_field(
struct Curl_easy *
data,
int certnum,
798 const char *label, curl_asn1Element *elem)
804 output = Curl_ASN1tostr(elem, 0);
807 Curl_ssl_push_certinfo(data, certnum, label, output);
809 infof(data,
" %s: %s\n", label, output);
810 free((
char *) output);
814 static void do_pubkey(
struct Curl_easy *data,
int certnum,
815 const char *algo, curl_asn1Element *param,
816 curl_asn1Element *pubkey)
818 curl_asn1Element elem;
828 Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
831 p = Curl_getASN1Element(&elem, pk.beg, pk.end);
833 for(q = elem.beg; !*q && q < elem.end; q++)
835 len = (
unsigned long)((elem.end - q) * 8);
837 for(i = *(
unsigned char *) q; !(i & 0x80); i <<= 1)
842 infof(data,
" RSA Public Key (%lu bits)\n", len);
846 Curl_ssl_push_certinfo(data, certnum,
"RSA Public Key", q);
851 do_pubkey_field(data, certnum,
"rsa(n)", &elem);
852 Curl_getASN1Element(&elem, p, pk.end);
853 do_pubkey_field(data, certnum,
"rsa(e)", &elem);
856 p = Curl_getASN1Element(&elem, param->beg, param->end);
857 do_pubkey_field(data, certnum,
"dsa(p)", &elem);
858 p = Curl_getASN1Element(&elem, p, param->end);
859 do_pubkey_field(data, certnum,
"dsa(q)", &elem);
860 Curl_getASN1Element(&elem, p, param->end);
861 do_pubkey_field(data, certnum,
"dsa(g)", &elem);
862 do_pubkey_field(data, certnum,
"dsa(pub_key)", &pk);
865 p = Curl_getASN1Element(&elem, param->beg, param->end);
866 do_pubkey_field(data, certnum,
"dh(p)", &elem);
867 Curl_getASN1Element(&elem, param->beg, param->end);
868 do_pubkey_field(data, certnum,
"dh(g)", &elem);
869 do_pubkey_field(data, certnum,
"dh(pub_key)", &pk);
883 curl_X509certificate cert;
885 curl_asn1Element param;
891 unsigned long version;
902 if(Curl_parseX509(&cert, beg, end))
906 ccp = Curl_DNtostr(&cert.subject);
910 Curl_ssl_push_certinfo(data, certnum,
"Subject", ccp);
912 infof(data,
"%2d Subject: %s\n", certnum, ccp);
916 ccp = Curl_DNtostr(&cert.issuer);
920 Curl_ssl_push_certinfo(data, certnum,
"Issuer", ccp);
922 infof(data,
" Issuer: %s\n", ccp);
927 for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
928 version = (version << 8) | *(
const unsigned char *) ccp;
933 Curl_ssl_push_certinfo(data, certnum,
"Version", ccp);
937 infof(data,
" Version: %lu (0x%lx)\n", version + 1, version);
940 ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
944 Curl_ssl_push_certinfo(data, certnum,
"Serial Number", ccp);
946 infof(data,
" Serial Number: %s\n", ccp);
950 ccp = dumpAlgo(¶m, cert.signatureAlgorithm.beg,
951 cert.signatureAlgorithm.end);
955 Curl_ssl_push_certinfo(data, certnum,
"Signature Algorithm", ccp);
957 infof(data,
" Signature Algorithm: %s\n", ccp);
961 ccp = Curl_ASN1tostr(&cert.notBefore, 0);
965 Curl_ssl_push_certinfo(data, certnum,
"Start Date", ccp);
967 infof(data,
" Start Date: %s\n", ccp);
971 ccp = Curl_ASN1tostr(&cert.notAfter, 0);
975 Curl_ssl_push_certinfo(data, certnum,
"Expire Date", ccp);
977 infof(data,
" Expire Date: %s\n", ccp);
981 ccp = dumpAlgo(¶m, cert.subjectPublicKeyAlgorithm.beg,
982 cert.subjectPublicKeyAlgorithm.end);
986 Curl_ssl_push_certinfo(data, certnum,
"Public Key Algorithm", ccp);
988 infof(data,
" Public Key Algorithm: %s\n", ccp);
989 do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey);
995 ccp = Curl_ASN1tostr(&cert.signature, 0);
999 Curl_ssl_push_certinfo(data, certnum,
"Signature", ccp);
1001 infof(data,
" Signature: %s\n", ccp);
1006 cert.certificate.end - cert.certificate.beg,
1018 i = 28 + cl1 + (cl1 + 64 - 1) / 64 + 26;
1025 i = copySubstring(cp2,
"-----BEGIN CERTIFICATE-----");
1026 for(j = 0; j < cl1; j += 64)
1027 i += copySubstring(cp2 + i, cp1 + j);
1028 i += copySubstring(cp2 + i,
"-----END CERTIFICATE-----");
1032 Curl_ssl_push_certinfo(data, certnum,
"Cert", cp2);
1034 infof(data,
"%s\n", cp2);
1041 #if defined(USE_GSKIT) 1043 static const char *checkOID(
const char *beg,
const char *end,
1054 ccp = Curl_getASN1Element(&e, beg, end);
1055 if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
1056 return (
const char *) NULL;
1058 p = OID2str(e.beg, e.end,
FALSE);
1060 return (
const char *) NULL;
1062 matched = !strcmp(p, oid);
1064 return matched? ccp: (
const char *) NULL;
1068 const char *beg,
const char *end)
1071 curl_X509certificate cert;
1072 curl_asn1Element dn;
1073 curl_asn1Element elem;
1074 curl_asn1Element ext;
1075 curl_asn1Element
name;
1080 size_t addrlen = (
size_t) -1;
1088 struct in6_addr addr;
1090 struct in_addr addr;
1099 if(Curl_parseX509(&cert, beg, end))
1105 addrlen =
sizeof(
struct in6_addr);
1109 addrlen =
sizeof(
struct in_addr);
1112 for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) {
1113 p = Curl_getASN1Element(&ext, p, cert.extensions.end);
1115 ext.beg = checkOID(ext.beg, ext.end, sanOID);
1117 ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
1119 if(elem.tag == CURL_ASN1_BOOLEAN)
1120 ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
1122 Curl_getASN1Element(&elem, elem.beg, elem.end);
1124 for(q = elem.beg; matched != 1 && q < elem.end;) {
1125 q = Curl_getASN1Element(&name, q, elem.end);
1128 len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
1129 name.beg, name.end);
1130 if(len > 0 && (
size_t)len == strlen(dnsname))
1138 matched = (
size_t) (name.end - q) == addrlen &&
1139 !memcmp(&addr, q, addrlen);
1149 infof(data,
"\t subjectAltName: %s matched\n", dispname);
1154 infof(data,
"\t subjectAltName does not match %s\n", dispname);
1160 name.beg = name.end =
"";
1161 q = cert.subject.beg;
1164 while(q < cert.subject.end) {
1165 q = Curl_getASN1Element(&dn, q, cert.subject.end);
1166 for(p = dn.beg; p < dn.end;) {
1167 p = Curl_getASN1Element(&elem, p, dn.end);
1169 elem.beg = checkOID(elem.beg, elem.end, cnOID);
1176 if(!Curl_getASN1Element(&elem, name.beg, name.end))
1177 failf(data,
"SSL: unable to obtain common name from peer certificate");
1179 len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end);
1184 if(strlen(dnsname) != (
size_t) len)
1185 failf(data,
"SSL: illegal cert name field");
1187 infof(data,
"\t common name: %s (matched)\n", dnsname);
1192 failf(data,
"SSL: certificate subject name '%s' does not match " 1193 "target host name '%s'", dnsname, dispname);
#define SSL_CONN_CONFIG(var)
CURLcode Curl_base64_encode(struct Curl_easy *data, const char *inputbuff, size_t insize, char **outptr, size_t *outlen)
#define strcasecompare(a, b)
TFSIMD_FORCE_INLINE const tfScalar & y() const
UNITTEST_START int result
struct ssl_config_data ssl
static srvr_sockaddr_union_t from
struct proxy_info http_proxy
memcpy(filename, filename1, strlen(filename1))
UNITTEST_START char * output
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
int Curl_inet_pton(int af, const char *src, void *dst)
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
UNITTEST_START int * value
CURL_EXTERN char * curl_maprintf(const char *format,...)